从 Activity.onCreate() 创建永不消亡的线程
我花了几个小时在这里寻找答案,但似乎没有什么能让我清楚。
这是我的问题:我有一个带有主菜单的简单应用程序。其中一个选项从 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 技术交流群。
发布评论
评论(3)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您正在主线程的 Looper 上调用 quit()。不是线程的Looper。
你可以试试这个。创建一个扩展
Thread
的单独的私有内部类。在 run() 方法中,调用 Looper.myLooper() 将线程的 Looper 实例保存在类中。然后有一个退出方法,在该循环器上调用 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: