奇怪的操作,处理程序在应用程序完成后仍然调用

Strange operation, Handler still call after application finish

我创建了一个简单的应用程序,它从 Internet 加载类别列表,然后加载到 UI...在 onCreate 上,我创建了一个线程来从 Internet 获取信息,然后显示给 UI...我使用接口在 activity 与线程 class 之间进行通信。问题是当我按返回键完成应用程序时,我看到线程仍然 运行 并且它仍然触发界面...

我的activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        Log.e("dj", "On Create!");
        setContentView(R.layout.activity_main);
        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        //Load category list
        DjModel.getInstance(this).doDownloadCategoryList();
        //Show dialog loading
        showLoadingDialog();
}
//The listener implement
@Override
public void onGetListCategoryDone(List<Category> list) {
    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            mDrawerLayout);
    //Dismiss dialog
    closeLoadingDialog();
    //Start service it wasn't
    if(mDownloadIntent == null){
        mDownloadIntent =  new Intent(this, DjVipDownloadService.class);
        bindService(mDownloadIntent, mDownloadServiceConnection, Context.BIND_AUTO_CREATE);
        startService(mDownloadIntent);
    }
}

我的 DjModel:

public class DjModel {


private static DjModel _model;
private final int MESSAGE_NOTIFY_GET_TRACKS_DONE = 1;
private final int MESSAGE_NOTIFY_GET_CATEGORY_DONE = 2;

public static DjModel getInstance(OnModelTaskDone callback){
    if(_model == null){
        _model = new DjModel(callback);
        _model.mListTrack = new ArrayList<>();
    }
    if(callback != null){
        _model.mOnModelTaskDone = callback;
    }
    return _model;
}
public void doDownloadCategoryList(){
    Thread thread = new Thread(new GetCategoryTask());
    thread.start();
}
private class GetCategoryTask implements Runnable{
    @Override
    public void run() {
        List<Category> list = new ArrayList<Category>();
        String json = Utils.getContentFromURL(Common.API_PLATFORM + Common.API_CATEGORY_LIST);
        try {
            JSONObject jsonObject = new JSONObject(json);
            //Get result
            int result = jsonObject.getInt("result");
            if(result == 1){//Success
                //Parse datas
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject data = jsonArray.getJSONObject(i);
                    //Pull the data
                    long id = data.getLong("id");
                    String name = data.getString("name");
                    //Create category
                    Category category = new Category();
                    category.setID(String.valueOf(id));
                    category.setName(name);
                    list.add(category);
                }
            }else{

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        //Set to global data
        DjModel.getInstance(null).setListCategory(list);
        mNotifyHandler.sendMessage(mNotifyHandler.obtainMessage(MESSAGE_NOTIFY_GET_CATEGORY_DONE));
    }
}
private Handler mNotifyHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case MESSAGE_NOTIFY_GET_CATEGORY_DONE:
                if(mOnModelTaskDone != null){
                    Log.e("dj","Fire event update category list");
                    mOnModelTaskDone.onGetListCategoryDone(DjModel.getInstance(null).getListCategory());
                }
                break;
        }

    }
};
}

一切正常运行 我第一次打开应用程序时一切正常。但是当我按下后退按钮时,我在 logcat:

上得到了这个
01-14 00:02:25.810  16917-16917/tn.han.app.djvip E/ActivityThread﹕ Activity tn.han.app.djvip.MainActivity has leaked ServiceConnection tn.han.app.djvip.MainActivity@2f0816c9 that was originally bound here
android.app.ServiceConnectionLeaked: Activity tn.han.app.djvip.MainActivity has leaked ServiceConnection tn.han.app.djvip.MainActivity@2f0816c9 that was originally bound here
        at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1072)
        at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:966)
        at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1768)
        at android.app.ContextImpl.bindService(ContextImpl.java:1751)
        at android.content.ContextWrapper.bindService(ContextWrapper.java:538)
        at tn.han.app.djvip.MainActivity.onGetListCategoryDone(MainActivity.java:630)
        at tn.han.app.djvip.model.DjModel.handleMessage(DjModel.java:336)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

(DjModel.java:336) 是:

mOnModelTaskDone.onGetListCategoryDone(DjModel.getInstance(null).getListCategory());

(MainActivity.java:630) 是:

bindService(mDownloadIntent, mDownloadServiceConnection, Context.BIND_AUTO_CREATE);

我不知道为什么即使我没有调用 doDownloadCategoryList() onGetListCategoryDone 仍然触发...

谢谢!

您遇到了几个问题。首先,线程不是生命周期感知的,所以当你的 activity 被关闭时,线程继续 运行。您必须停止它并取消您 activity 的 onPause 中的工作。其次,你正在启动一个 Service ,它给你一个 Binder 但是当你的 activity 被销毁时你没有调用 unbindService,所以 logcat 显示消息关于泄露的连接。

澄清最后一点:logcat 将问题显示为 ServiceConnection 未解除绑定。这确实是这里问题的根源。 logcat 输出中的堆栈跟踪没有显示崩溃发生的位置,而是 进行 bindService() 调用的位置 以帮助您追踪当 Activity 为 paused/stopped/destroyed.

时,需要在 unbindService() 调用中提供确切的 ServiceConnection 对象