android - RxJava运行在主线程而不是后台线程

标签 android rx-java2 android-contacts

我正在使用 RxJava2 来获取所有联系人并将其显示在 TextView 中。 我是 RxJava2 的新手,由于缺乏文档示例,发现它很困难。

这是我使用RxJava2从用户手机获取联系人列表的代码

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private Disposable disposable;
    private List<ContactsPOJO> contactsPOJOList;
    private Observable<List<ContactsPOJO>> contactObservable;
    private Observer<List<ContactsPOJO>> contactObserver;

    @SuppressLint("CheckResult")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.tv);
        contactsPOJOList = new ArrayList<>();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 100);
            } else {
                contactObservable = getContactObervable();

                contactObserver = getContactObserver();
                contactObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                        .filter(contactsPOJOS -> {
                            if(contactsPOJOS.size()>0){
                                Collections.sort(contactsPOJOS, (o1, o2) -> o1.getName().compareTo(o2.getName()));
                            }
                            //Java 8 and API 24
                            //contactsPOJOS.stream().sorted((object1,object2) -> object1.getName().compareTo(object2.getName()));
                            return true;
                        })
                        .subscribeWith(contactObserver);

                Log.i("TAG", "onCreate1: 1");


            }
        } else {
            contactObservable = getContactObervable();
            contactObserver = getContactObserver();
            contactObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeWith(contactObserver);
            Log.i("TAG", "onCreate1: 2");
             }
    }

    private Observer<List<ContactsPOJO>> getContactObserver() {
        Log.i("MainActivity1",""+Thread.currentThread().getName());
        return new Observer<List<ContactsPOJO>>() {
            @Override
            public void onSubscribe(Disposable d) {
                disposable = d;
            }

            @Override
            public void onNext(List<ContactsPOJO> contactsPOJOS) {
                for(ContactsPOJO i:contactsPOJOS){
                    textView.append(i.getName()+"\n"+i.getContactNo()+"\n");
                    Log.i("TAG", "onNext: "+i.getName()+"\n"+i.getContactNo()+"\n");
                }
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.i("TAG", "onComplete:All items emitted ");
            }
        };

    }

    private Observable<List<ContactsPOJO>> getContactObervable() {
        Log.i("MainActivity3",""+Thread.currentThread().getName());
        return Observable.just(getContact());
    }

    public List<ContactsPOJO> getContact() {
        Log.i("MainActivity3",""+Thread.currentThread().getName());
        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        if (cur != null && cur.getCount() > 0) {
            while (cur.moveToNext()) {
                String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                            null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                            new String[]{id},
                            null);
                    while (Objects.requireNonNull(pCur).moveToNext()) {
                        String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        contactsPOJOList.add(new ContactsPOJO(name, phoneNumber));
                    }
                    pCur.close();
                }
            }
        }
        cur.close();
        return contactsPOJOList;
    }


    @SuppressLint("CheckResult")
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 100) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                contactObservable = getContactObervable();

                contactObserver = getContactObserver();
                contactObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribeWith(contactObserver);
                Log.i("TAG", "onCreate1: 3");
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        disposable.dispose();
    }
}

我尝试打印日志语句来了解我正在哪个线程上运行,它显示我始终在主线程上运行。有人能指出我在这里做错了什么吗?

最佳答案

您使用 Observable.just() - 这意味着 getContact() 方法将在需要创建 Observable 之前被调用。因此,您的代码将始终在当前线程上调用(在您的情况下是主线程)。 要解决该问题,请使用 Observable.fromCallable() 而不是 Observable.just()

关于android - RxJava运行在主线程而不是后台线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52686203/

相关文章:

java - 响应式(Reactive)编程的优点/缺点

android - 如何在android的默认浏览器选择列表中添加我的浏览器?

android - 如何使用 Json 发布 HasMap 的多个值

java - 如何在 RxJava 中处理 dispose 而不会出现 InterruptedException

java - RxJava - 通过另一个控制一个 Observable

android - 安卓联系人图标存储技巧

Android:批量添加数千个电话簿中的联系人

Android- 使用 ViewHolder 和 AsyncTask 加载联系人- 缩略图问题

java - 使用 onTouchListener 旋转图像而不缩放图像

java - 如何使用两个主题?