【问题标题】:Why does Activity dies after starting a Service?为什么启动服务后Activity会死掉?
【发布时间】:2015-08-06 08:49:49
【问题描述】:

我想知道为什么会这样。我的 MainActivity 启动一个服务并将自身传递给该服务,因此该服务可以使用它获得的数据调用 MainActivity 的方法之一(我完全意识到这不是应该做的事情)。但是,当调用此方法时,Activity 中的每个字段都为 null,并且尝试调用 findViewById() 会导致 Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

这意味着Activity死了,但是怎么会呢? Activity 的生命周期还没有结束。为什么垃圾收集器把它拿走了?

请看一下代码:

MainActivity

public class MainActivity extends Activity implements Serializable{

    private RecyclerView mRecyclerView;
    private MyAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, Servicio.class);
        intent.putExtra("ACTIVITY", this);
        startService(intent);
    }

    public void loadList(List<Data>){
        mList = (LinkedList<Data> dataList;

        mRecyclerView = (RecyclerView) this.findViewById(R.id.rv);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mAdapter = new MyAdapter(this, mList);
        mRecyclerView.setAdapter(mAdapter);
    }
}

服务

public class MyService extends Service {

    private Thread mThread;
    private Activity mActivity;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mThread = new Thread(new Runnable() {
            @Override
            public void run() {
                execute();
            }
        });
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
        mActivity = (Activity) intent.getSerializableExtra("ACTIVITY");
        mThread.start();
        return super.onStartCommand(intent, flags, startId);
    }

    public void execute(){
        dataObtained = doStuff();
        ((MainActivity) mActivity).loadList(dataObtained);
    }
}

但是,如果我在服务中使用sendBroadcast() 来发回数据并通过在其中注册一个 BroadcastReceiver 在 Activity 中检索它,那么 Activity 仍然可以完全运行,我可以调用findViewById()。如何?生命周期之前什么时候结束,但在这种情况下没有结束?

【问题讨论】:

  • 我认为这与线程问题有关,但我不确定。我没有解决方案,但是,如果您想保持这种方式,最好将活动引用移动到应用程序类,并在 onStop 中将其无效并在 onStart 中绑定引用。在意图中传递活动引用是个坏主意。编辑:我不认为你可以序列化活动,即使它只是一个参考
  • 整体来说使用intents是个坏主意,哈哈哈。我只想知道原因;我永远不会真正编写这样的代码。
  • 我也不知道 =( 你有没有验证过这个 ---mActivity = (Activity) intent.getSerializableExtra("ACTIVITY") --- 真的有效?我的意思是它除了空?
  • the service so the service can call one of the MainActivity's methods 这是不好的方法
  • 你应该使用绑定服务和服务连接来与活动和服务交互...

标签: android android-activity android-lifecycle


【解决方案1】:

你做错了mActivity = (Activity) intent.getSerializableExtra("ACTIVITY");它有效吗?

您可以使用LocalBroadcastManagerOtto在Service和Activity之间进行通信

【讨论】:

    【解决方案2】:

    您可以使用广播进行通信,消息处理程序,但不是这个。这只是简单的不好的做法(因此没有“好的”答案可以让您满意)。更不用说您使用此技术的成功将为整个 Android 带来的安全问题(我在这里要说的是,这很可能是不可能的)。

    您应该重新考虑是否过于热衷于维护 Activity 的序列化,因为如果这很容易,最终您将不会使用 StackOverflow,而且没有好的程序员可以真正帮助您,因为没有好的程序员会这样做。

    【讨论】:

    • 请阅读我提出的问题。正如帖子中所述,我已经知道这是不好的做法。我只想知道为什么当我这样做时活动会消失。这已经解决了。所以,请不要再发“我比你优秀”的帖子了。
    • 这不是要优于你。是为了帮助你。您明确表示您知道这是错误的,但无论如何您仍想继续进行。 techterms.com/definition/gigo
    • 我想知道“为什么”,而不是那样做。但是,你说“这不是好的做法”,我已经知道了,“没有令人满意的答案”,但最终还是有。
    • 好吧,您似乎有了答案:Android 上下文对象的序列化不起作用。另外,您发现 Activity 实际上并没有被销毁。我承认我很困惑为什么有人会故意编写糟糕的代码然后公开询问为什么它不起作用,但这是你的问题。
    • 我指的是使用一个活动来发送回调,而不是序列化一个活动。我故意做了前者,但不是后者。此外,不好的做法并不意味着没有工作方法;这意味着,不能做的方法。所以我没有写不好的代码来知道为什么它不起作用,我写了一个不可取的。
    【解决方案3】:

    好的,我解决了。碰巧,在序列化对象时,您在接收活动中没有得到相同的对象。 thismActivity 对象都有不同的 ID。

    【讨论】:

    • 你为什么一直投反对票而不提供任何解释?你觉得我能从中学到什么吗?
    猜你喜欢
    • 2011-10-25
    • 2015-06-22
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    相关资源
    最近更新 更多