从 Activity.onCreate() 创建永不消亡的线程

发布于 11-29 04:55 字数 2960 浏览 0 评论 0原文

我花了几个小时在这里寻找答案,但似乎没有什么能让我清楚。

这是我的问题:我有一个带有主菜单的简单应用程序。其中一个选项从 PHP 服务器检索注释列表,更新数据库,然后显示 ListView。

里面一切正常。现在,每次我按回键然后再次启动活动时,都会启动一个新线程。我设法获得了超过 50 个等待线程。我正在使用 Eclipse 中的 DDMS 选项卡来监视步骤。

如果我尝试调用 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;
        }
    }

}

I have spent last couple of hours searching for answers here but nothing seems to make it clear for me.

Here's my problem: I have a simple app with a main menu. One of the options retrieves a list of comments from a PHP server, updates the database and then displays a ListView.

Everything functions properly inside. Now, every time I press back and then start the activity again, a new thread is started. I managed to get to more than 50+ waiting threads. I'm using the DDMS tab from Eclipse to monitor the treads.

If I try to call Looper.getLooper().quit() or Looper.myLooper().quit() I get an error saying "main thread not allowed to quit".

What am I doing wrong and where/how should I be stopping the thread?

Here's the code:

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;
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩人痒2024-12-06 04:55:51

您正在主线程的 Looper 上调用 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();
   }
}

You're calling quit() on your main thread's Looper. Not the thread's Looper.

You can try this. Create a separate private inner-class that extends Thread. In the run() method, do a call to Looper.myLooper() to save the thread's Looper instance in the class. Then have a quitting method that calls quit on that looper.

Example:

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();
   }
}
庆幸我还是我2024-12-06 04:55:51

在您的 onDestroy 方法中,您是否进行任何调用来停止线程?

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

}

On your onDestroy method do you make any calls to stop the thread?

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

}
暮光沉寂2024-12-06 04:55:51

您正在主 (UI) 线程中调用 Looper.quit() 方法,这是不允许的。尝试将 Runnable 发布到调用 Looper.quit() 的线程内的处理程序。这将导致线程上下文中的Looper退出。

You are calling the Looper.quit() method within your main (UI) thread, which is not allowed. Try posting a Runnable to the handler inside your thread that calls Looper.quit(). This will cause the Looper within the thread context to quit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文