Android 片段内的线程
我有一个应用程序使用了一个带有视图寻呼机的片段。我查询android联系人数据库(这应该很快),以获取每个联系人的主要号码,并显示在列表视图中。问题是,这似乎需要一些时间。我尝试在onCreateView和“更新”中使用线程和异步任务,或者为联系人列表设置适配器。当我这样做时,我会遇到一些错误: 无法在未调用Looper.prepare()的线程内创建处理程序 我尝试使用Looper.prepare(),但它仍然会崩溃 所以我加入了一个处理程序,但当人们启动我的应用程序时会出现延迟Android 片段内的线程,android,multithreading,android-fragments,Android,Multithreading,Android Fragments,我有一个应用程序使用了一个带有视图寻呼机的片段。我查询android联系人数据库(这应该很快),以获取每个联系人的主要号码,并显示在列表视图中。问题是,这似乎需要一些时间。我尝试在onCreateView和“更新”中使用线程和异步任务,或者为联系人列表设置适配器。当我这样做时,我会遇到一些错误: 无法在未调用Looper.prepare()的线程内创建处理程序 我尝试使用Looper.prepare(),但它仍然会崩溃 所以我加入了一个处理程序,但当人们启动我的应用程序时会出现延迟 final
final Runnable setupView = new Runnable() {
@Override
public void run() {
contactos = con.getContactSearch("");
setupContacts();
}
};
其中:
getContactSearch:
public HashMap<String, ContactInfo> getContactSearch(String _where)
{
contactInfo = new HashMap<String, ContactInfo>();
Cursor cursor = null ;
if(_where.length()==0)
{
cursor = getContacts();
}else
{
cursor = getContactsFilter(_where);
}
try
{
while (cursor.moveToNext()) {
String id = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
if(!contactInfo.containsKey(id))
{
String displayName = cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
//obtenemos el telefono principal
//String number = "" ;//getPrimaryNumber(id);
ContactInfo ci = new ContactInfo(displayName,"",id);
contactInfo.put(id,ci);
}
}
getPrimaryNumbers();
}finally
{
cursor.close();
}
return contactInfo;
}
我如何异步执行此操作?我想知道如果我只在onCreate()中搜索联系人会发生什么,如果它比onCreateView快,ListView将为空。这样做“有效”,但有很大的滞后。
如何优化此过程?您的setupContacts()方法会处理UI内容,这在UI线程之外是无法完成的。您必须创建一个新的Runnable并将其发布到UI线程视图活动中。runOnUiThread()或view.post()
如果这看起来像是令人恼火的陈词滥调,那就是。创建的目的是简化在后台做事情然后发布到UI线程的模型
使用AsyncTasks的一个问题是,在任务完成时,启动它的活动可能已死亡。如果是配置更改(例如设备旋转),您仍然需要数据,但asynctask指向一个死引用。在最好的情况下什么也不会发生,在最坏的情况下,您会得到一个空指针异常。这确实令人沮丧,因为片段可以很好地经受住这些配置更改
是为了解决这个问题而创建的。API文档中有一个AsyncTaskLoader示例,它在获取一些数据后填充适配器。使用
LoaderManager
来管理此示例。在循环中获取联系人总是非常慢。如果您将某些信息显示为ListView的一部分,而该行的其他部分的获取速度比联系人信息快,我建议您延迟加载速度较慢的部分。我想我的问题是使用CUrsorLoader,我现在使用getcontentresolver,也许我将所有内容移动到Loader,现在似乎快了一点:)我使用这个网站来使用AsynTaskLoader,因为使用Loader会让人困惑,这会有所帮助
mAdapter = new DialerContactsAdapter(contactos,getActivity());
listaContactos.setAdapter(mAdapter);
listaContactos.setFastScrollEnabled(true);
listaContactos.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
mAdapter.mBusy = false;
mAdapter.notifyDataSetChanged();
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
mAdapter.mBusy = false;
mAdapter.notifyDataSetChanged();
break;
case OnScrollListener.SCROLL_STATE_FLING:
mAdapter.mBusy = true;
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});