2015-01-13 1 views
0

Я создаю простое приложение, которое загружает список категорий из Интернета, затем загружается в пользовательский интерфейс ... В onCreate я создаю поток для извлечения информации из Интернета, а затем показываю на UI ... Я использую интерфейс для связи между активностью с классом потоков. Проблема заключается в том, когда я нажимаю назад, чтобы закончить приложение, я увидел, что нить по-прежнему работать, и это до сих пор огонь интерфейс ...Странная операция, обработчик все еще звонит после завершения приложения

Моя активность:

@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 [email protected] that was originally bound here 
android.app.ServiceConnectionLeaked: Activity tn.han.app.djvip.MainActivity has leaked ServiceConnection [email protected] 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$1.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); 

Я не знаю, почему onGetListCategoryDone до сих пор стрелять даже я не назвал doDownloadCategoryList() ...

Спасибо!

ответ

1

У вас есть пара вопросов. Во-первых, поток не является жизненным циклом, поэтому, когда ваша активность отклоняется, поток продолжает работать. Вы должны остановить его и отменить работу в вашей деятельности . Во-вторых, вы начинаете Service, который дает вам Binder, но вы не вызываете unbindService, когда ваша деятельность уничтожена, поэтому в логарифме отображается сообщение о просочившемся соединении.

Чтобы уточнить последний пункт: лог-код показывает проблему, поскольку ServiceConnection не является несвязанным. Это действительно источник проблемы. Трассировка стека в выводе logcat не показывает, где произошел сбой, а скорее , где был сделан вызов bindService(), чтобы помочь вам отслеживать точный объект ServiceConnection, который необходимо предоставить в вызове unbindService(), когда Activity является паузу/остановить/уничтожены.

+0

Incase thread продолжает работать, почему onGetListCategoryDone все еще звонит? Я не называл doDownloadCategoryList, так почему он все еще звонит? Я застрял в нем. Кстати, вы сказали, что я должен остановить и отменить работу, что мне делать? –

+0

Код 'Activity' вызывает' doDownloadCategoryList() '. Это одна из вещей, которые она делает в своем 'onCreate()'. Это заставляет поток запускаться, и когда он заканчивается, он отправляет 'Message' в' Handler', который привязан к основному потоку вашего приложения и который, в свою очередь, вызывает 'bindServce()'. Чтобы исправить это, вашей «Деятельности» нужно будет поддерживать ссылку на текущий «поток» и остановить ее, когда она выйдет. 'AsyncTask' доступен только для этой цели, но может вызвать подобные проблемы, если вы не будете осторожны. Эта статья может помочь: http://po.st/Cei3m2 –

+0

Значит, вы имеете в виду вызов onCreate дважды? Я делаю небольшой тест следующим образом: после вызова onGetListCategoryDone я установил mOnModelTaskDone равным null, а затем, когда я нажму кнопку «Назад». logcat все еще показывает ошибку, когда огонь onGetListCategoryDone, почему ??? Я думаю, проблема не в том, как я останавливаю или отменю поток, потому что он просто запускается, когда я вызываю doDownloadCategory ... hmmm Очень странно !!! –

Смежные вопросы