【问题标题】:Android: Run a thread in the background without delaying activityAndroid:在后台运行线程而不延迟活动
【发布时间】:2014-06-04 23:43:37
【问题描述】:

我有一个提取联系信息的过程,它需要很长时间 - 4 秒。我不希望它干扰我的应用程序中的用户体验。我有两个问题:

  1. 如何在它自己的线程中运行它,这样它才不会延迟 Activity 在屏幕上的绘制
  2. 有没有办法加快这个速度? (我这样做效率低吗?)

我尝试从 onCreate、onStart 和 onResume 调用下面的 getContacts() 方法,但在所有情况下,直到方法完全运行后屏幕才会出现。

代码如下:

private void getContacts() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            try {
                Log.d("ManageFriends","getContacts Start");
                ContentResolver cr = getContentResolver();
                String[] PROJECTION = new String[] {
                        ContactsContract.CommonDataKinds.Email.CONTACT_ID,
                        ContactsContract.Contacts.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Email.ADDRESS,
                        ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
                };
                String filter = ContactsContract.CommonDataKinds.Email.ADDRESS + " NOT LIKE '' AND 1 == " +
                        ContactsContract.Contacts.IN_VISIBLE_GROUP + " AND " +
                        ContactsContract.Contacts.DISPLAY_NAME + " NOT LIKE '%@%'";
                Cursor cur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, filter, null, null);
                DBHelper.insertArrayList(db,"Contacts",DBHelper.cursorToArrayList(cur));
                Log.d("ManageFriends","getContacts End");
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    thread.run();
}

注意:我知道这个过程缓慢的主要原因 - 我将游标结果转换为 ArrayList >,然后将其插入 SQLite db。但如果我能让它在后台运行,我会很高兴。

【问题讨论】:

  • 关于你的问题的Part 1,它已经在一个单独的线程上,它不应该对你的活动活动的屏幕布局有任何影响,除非显示的内容依赖于在您的线程中获得的信息。
  • 要定期更新屏幕,您需要从线程调用回 UI 线程来更新屏幕。这将使应用看起来更具响应性。
  • 使用AsyncTask 进行线程化。容易多了。 developer.android.com/reference/android/os/AsyncTask.html
  • like '' 可能效率不高,我会直接使用= ''
  • 使用thread.start() 启动线程。 thread.run()直接在当前线程中调用线程的方法。

标签: java android multithreading android-lifecycle android-cursor


【解决方案1】:

考虑使用daemon 线程。

Daemon 线程通常用于为您的应用程序/小程序执行服务(例如加载“fiddley bits”)。用户线程和守护线程的核心区别在于,JVM 只会在所有用户线程都终止后才会关闭程序。当不再有任何用户线程(包括执行的主线程)在运行时,JVM 会终止守护线程。

附注这是一个低优先级线程

来源:

示例

Thread thread = new Thread();

thread.setDaemon(true);

thread.start();

编辑!

查看link 中的AsyncTask,这是 UI 后台任务的线程。

【讨论】:

  • 文档说This is not normally relevant to applications with a UI.
  • 我使用了 thread.start() ,它有所作为。我省略了 setDaemon,这对我的情况没有影响。
  • @Scott 我为你编辑了一些有用的信息!
  • @njzk2 在AsyncTask 中编辑,专门用于 UI 线程
【解决方案2】:

考虑在后台线程中使用从 ContentProvider 加载数据的 CursorLoader:Retrieving a List of Contacts

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多