Создание потоков из Activity.onCreate (), которые никогда не умирают - PullRequest
3 голосов
/ 12 августа 2011

Последние пару часов я потратил на поиск ответов, но, похоже, мне ничего не понятно.

Вот моя проблема: у меня есть простое приложение с главным меню. Одна из опций получает список комментариев с PHP-сервера, обновляет базу данных и затем отображает ListView.

Внутри все работает правильно. Теперь, каждый раз, когда я нажимаю назад и затем снова запускаю упражнение, запускается новый поток. Мне удалось получить более 50 ожидающих потоков. Я использую вкладку DDMS из Eclipse для мониторинга протекторов.

Если я пытаюсь позвонить Looper.getLooper().quit() или Looper.myLooper().quit(), я получаю сообщение об ошибке "основной поток не может выйти".

Что я делаю не так, и где / как я должен остановить поток?

Вот код:

public class RequestActivity extends Activity {

    ProgressDialog pDialog;
    DatabaseHelper db;
    int userId;
    myCursorAdapter adapter;
    Thread runner = null;
    ListView list;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userId = myApplication.getInstance().getSession().getUserId();
        setContentView(R.layout.request_list);

        db = new myProvider.DatabaseHelper(this);
        Cursor cursor = db.getRequests(userId);
        startManagingCursor(cursor);
        adapter = new myCursorAdapter(RequestActivity.this, cursor);
        list = (ListView) findViewById(R.id.list);
        list.setVisibility(View.INVISIBLE);
        list.setAdapter(adapter);

        pDialog = ProgressDialog.show(RequestActivity.this, "", "Loading ...", true, false);

        runner = new Thread() {
            Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    adapter.getCursor().requery(); 
                }
            };  

            public void run() {
                Looper.prepare();
                // ... setup HttpGet
                try {
                    // ... get HTTP GET response 
                    if (response != null) {
                        // ... update database
                        handler.sendEmptyMessage(0);
                    }
                } catch(Exception e) {
                    // .. log exception
                }
                Looper.loop();
            }
        };
        runner.start();
    }

    private static class ViewHolder {
        // .. view objects
    }

    private class myCursorAdapter extends CursorAdapter {
        private LayoutInflater inflater;
        public myCursorAdapter(Context context, Cursor c) {
            super(context, c);
            inflater = LayoutInflater.from(context);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // .. bind data
            if (cursor.isLast()) {
                pDialog.dismiss();
                list.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View view = inflater.inflate(R.layout.request_list_item, parent, false);
            ViewHolder holder = new ViewHolder();
            // .. set holder View objects
            view.setTag(holder);
            return view;
        }
    }

}

Ответы [ 3 ]

2 голосов
/ 12 августа 2011

Вы вызываете quit () в Looper вашего основного потока.Не нить Лупер.

Вы можете попробовать это.Создайте отдельный закрытый внутренний класс, который расширяет Thread.В методе run () вызовите Looper.myLooper (), чтобы сохранить экземпляр Looper потока в классе.Затем создайте метод выхода, который вызывает команду quit для этого петлителя.

Пример:

private class LooperThread extends Thread{
   private Looper threadLooper;

   @Override
   public void run(){
      Looper.prepare();
      threadLooper = Looper.myLooper();
      Looper.loop();
   }

   public void stopLooper(){
      if(threadLooper != null)
          threadLooper.quit();
   }
}
1 голос
/ 12 августа 2011

В вашем методе onDestroy вы делаете какие-либо вызовы, чтобы остановить поток?

public void onDestroy()
{
    Thread moribund = runner;
    runner = null
    moribund.interrupt();

}
1 голос
/ 12 августа 2011

Вы вызываете метод Looper.quit() в своем основном потоке (UI), что недопустимо.Попробуйте опубликовать Runnable в обработчике в вашей ветке, который вызывает Looper.quit().Это приведет к выходу Looper в контексте потока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...