片段内的线程

时间:2013-05-07 18:26:48

标签: android multithreading android-fragments

我有一个使用Fragment和View寻呼机的应用。我查询android联系人数据库(这应该很快),以获得在ListView中显示的每个联系人的主要数字。问题是,这似乎需要一些时间。我试图在onCreateView中使用一个Thread和一个ASyncTask并“更新”或为我的联系人列表设置我的适配器。当我这样做时,我遇到了一些错误:

  

无法在未调用Looper.prepare()

的线程内创建处理程序

我尝试使用Looper.prepare()但它仍会崩溃。

所以我放入了一个处理程序,但是当人们启动我的应用程序时存在延迟

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

和setupcontacts:

    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

            }
        });

我是如何异步执行此操作的?我想知道我是否只在onCreate()中搜索联系人会发生什么,如果它比onCreateView更快,ListView将为null。这样做“有效”,但存在很大的滞后。 我如何优化这个过程?

1 个答案:

答案 0 :(得分:2)

你的setupContacts()方法摆弄了UI的东西,你不能在UI线程之外做。您必须创建一个新的Runnable并将其发布到UI线程视图Activity.runOnUiThread()或View.post()。

如果这看起来像是刺激性的样板,那就是。创建AsyncTask的目的是简化这种在后台执行操作的模型,然后发布到UI线程。

使用AsyncTasks的一个问题是,在任务完成时,启动它的Activity可能已经死了。如果是配置更改(例如设备轮换),您仍然需要数据,但是asynctask指向死引用。最好的情况是,没有任何反应,你得到一个空指针异常。这真是令人沮丧,因为Fragments可以在这些配置更改中幸存下来。

AnsyncTaskLoader是为了解决这个问题而创建的。 API文档中有一个AsyncTaskLoader示例,它在获取一些数据后填充适配器。