【问题标题】:Android Service hanging after returning to the activity返回活动后Android服务挂起
【发布时间】:2016-02-18 18:31:41
【问题描述】:

我觉得这个问题很有趣,有些可能不会。希望我能得到一个可靠的答案。

我有一个 Fragment,它在onResume() 中绑定了一个服务,以便在用户在场时每 60 秒自动刷新一次数据。我的bind() 方法在这里...

public void bind() {
    if(connected || MainActivity.sRefresherBinding) return;
    MainActivity.sRefresherBinding = true;
    Log.v(LOG_TAG, "binding...");
    mProgressDialog.setTitle("Service Connected!");
    mProgressDialog.setMessage("We're almost there!");
    Intent bindingIntent = new Intent(getActivity(), Refresh.class);
    getActivity().bindService(bindingIntent, mConnection, Context.BIND_AUTO_CREATE);
    getActivity().startService(bindingIntent);
}

对应的unbind()方法在这里调用在onStop()...

public void unbind() {
        Log.v(LOG_TAG, "unbinding");
        if (connected) {
            mRefreshService.terminate();
            getActivity().unbindService(mConnection);
            getActivity().stopService(new Intent(getActivity(), Refresh.class));
            connected = false;
        }
    }

onServiceConnected()这里...

public void onServiceConnected(ComponentName name, IBinder service) {
        if(binder != null) binder = null;
        binder = (Refresh.LocalBinder) service;
        if(mRefreshService != null) mRefreshService.terminate();
        mRefreshService = binder.getService();
        connected = true;
        mProgressDialog.setTitle("Refreshing your data...");
        mProgressDialog.setMessage("We are almost there!");
        Log.v(LOG_TAG, "Service Connected");
    }

我的 onStartCommand() 刷新扩展服务

public int onStartCommand(Intent intent, int flags, int startId) {
    start(new UpdateListener() {
        @Override
        public void onUpdate(ArrayList<Quote.SingleQuote> newData) {
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction(Utility.BROADCAST);
            broadcastIntent.putExtra(Utility.QUOTE_INTENT, newData);
            sendBroadcast(broadcastIntent);
        }
    });

    if (mHandler == null) {
        mHandler = new Handler();
        mHandler.post(mRunnable);
    }

    return Service.START_STICKY;
}

可运行的...

private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        refreshMain();
        if (mHandler != null)
            mHandler.postDelayed(this, MIN_UPDATE_TIME);
    }
};

refreshMain 太大了,我把结果发回监听器的 sn-p 贴一下……

call.enqueue(new Callback<Quote>() {

            @Override
            public void onResponse(Response<Quote> response) {
                try {                        
                    List<Quote.SingleQuote> asList = response.body().query.results.getQuote();
                    mQuotes = new ArrayList<>(asList);
                    mListener.onUpdate(mQuotes);
                    Log.v(LOG_TAG, "Refreshed");

                }

最后是我的广播接收器...

public static class UpdateReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(final Context context, final Intent intent) {

        if(MainFragmentService.getInstance().mProgressDialog != null) MainFragmentService.getInstance().mProgressDialog.dismiss();
        if(MainFragmentService.getInstance() != null) {
            MainFragmentService.getInstance().mQuotes = intent.getParcelableArrayListExtra(Utility.QUOTE_INTENT);
            MainFragmentService.getInstance().mAdapter.swapList(MainFragmentService.getInstance().mQuotes);
            Log.v(LOG_TAG, "Package received");
            MainActivity.sRefresherBinding = false;
        }
    }
}

这是棘手的部分。 所有这些代码在我的 nexus 5 上运行良好,但是当我在我的 Nexus 7 上运行它时,进入另一个 Activity 并返回,服务挂起。数据被获取、广播、拾取,但对话框不会被关闭,数据也不会显示在回收站视图中。

看看我的 Nexus 5 上的 logcat:

V/MainFragmentService: onPause
V/MainFragmentService: unbinding
V/MainFragmentService: onStop
V/MainFragmentService: onResume
V/MainFragmentService: binding...
V/Refresh: RefreshMain called
V/MainFragmentService: Service Connected
V/Refresh: Refreshed
V/MainFragmentService: Package received

现在看看我的 Nexus 7 上的 logcat:

V/MainFragmentService: onPause
V/MainFragmentService: unbinding
V/MainFragmentService: onStop
V/MainFragmentService: onResume
V/MainFragmentService: binding...
V/MainFragmentService: onResume
V/Refresh: RefreshMain called
V/MainFragmentService: Service Connected
V/Refresh: Refreshed
V/MainFragmentService: Package received
V/Refresh: Waiting
V/Refresh: Waiting
V/Refresh: RefreshMain called
V/Refresh: Refreshed
V/MainFragmentService: Package received

如果您对这段代码的工作有任何疑问,该应用程序就在这里,请转至nuts。如果您通读本文,感谢您的宝贵时间!

【问题讨论】:

  • 嗯,我通读到最后.. 不幸的是,不知道为什么它不令人耳目一新!当对话框没有关闭但您旋转平板电脑时,Nexus 7 上会发生什么 - 旋转时它会自行排序吗?
  • @MarkKeen 我在清单中添加了一行,以防止活动在配置更改时被破坏,因为再次在 Nexus 7 上,它正在使用相同的服务创建多个线程。对服务器的多次调用,它们都在广播,并且它们都没有填充回收器视图。我还没有尝试从清单中删除该行,因为在 bind() 和 service connected() 中添加了控件。我一回到我的电脑上就试试。
  • @MarkKeen 我可以确认这些控件有效地防止了服务被多次实例化。不能对片段说同样的话。 logcat 当我旋转设备几次时会发生什么。那是在我的手机上,无论混乱如何,信息都会更新和显示。我会调查一下。无论如何,在互联网上搜索了几个小时后,Nexus 7 上的问题仍然存在。
  • 如何停止您的Runnable?我不明白当您有 if (mHandler != null) mHandler.postDelayed(this, MIN_UPDATE_TIME); 运行每个 MIN_UPDATE_TIME 时,它是如何停止在您的 Nexus 5 上运行的。
  • @RicardoLage unbind() 在 Fragment 的 onStop() 中调用。问题不在 Nexus 5 上,而在 Nexus 7 上。实际上,我已经从使用不同设备(摩托罗拉、三星、LG)和不同版本的 Android 的人们的反馈中确认,该应用程序按照程序运行。我还没有找到可以复制该问题的其他设备。

标签: android android-fragments android-service android-broadcast android-broadcastreceiver


【解决方案1】:

问题追踪到开发人员选项 > 应用 > 不要在 Nexus 7 上启用活动,在 Nexus 5(和其他)上禁用。

这意味着真正的问题在于 Activity 本身,它在离开时被破坏了。导航回来时,由于我没有检查savedInstanceState,因此在现有片段之上创建了一个新片段。上面的 cmets 中提到的混乱现在也得到了修复,不再需要通过 Manifest 来防止配置更改时的活动破坏。

getFragmentManager().beginTransaction().add(R.id.content_main_list_container,
new MainFragmentService(), FRAGMENT_TAG_MAIN_LIST).commit();

现在是……

MainFragmentService mainFragment;
        if(savedInstanceState == null) {
            mainFragment = new MainFragmentService();
            getFragmentManager()
                    .beginTransaction()
                    .add(R.id.content_main_list_container,
                            mainFragment, FRAGMENT_TAG_MAIN_LIST)
                    .commit();
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多