【问题标题】:how to replace AsyncTask by RxAndroid如何用 RxAndroid 替换 AsyncTask
【发布时间】:2017-09-21 17:19:51
【问题描述】:

我正在尝试使用 RxAndroid 来完成与 AsyncTask 完全相同的工作。我编写了一个简单的示例,我在编辑文本中输入了一个 n 整数,当我按下 一个按钮,我使用“SystemClock.sleep”让线程睡眠 3 秒,当线程睡眠时,我显示一个进度条,当这三秒 过去进度条会消失,edittext中输入的值将乘以10并显示在atextview中。

通常,当我使用 AsyncTask 时,我会在 onPreExecute 中显示进度条,并使其在 onPostExecute 中消失。但是当我运行下面的代码时,我收到了 以下错误:

Only the original thread that created a view hierarchy can touch its views.

如何在 RxAndroid 中正确处理?

代码

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();
private EditText mEditTextValueToProcess = null;
private Button mButtonGoAsynchronous = null;
private TextView mTextViewProcessedValue = null;
private ProgressBar mProgressBar = null;
private rx.Observable<String> mAsyncObservable = null;

Subscriber mAsyncSubscriber = new Subscriber<String>() {
    @Override
    public void onCompleted() {
        Log.w(TAG, "onCompleted");
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void onError(Throwable e) {
        Log.w(TAG, "onError: " + e.getMessage().toString());
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void onNext(String o) {
        Log.w(TAG, "onNext:->after processing " + o);
        mTextViewProcessedValue.setText(o);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    intiViews();

    mAsyncObservable = rx.Observable.create(new rx.Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            mProgressBar = (ProgressBar) findViewById(R.id.progressDialog);
            mProgressBar.setVisibility(View.VISIBLE);

            SystemClock.sleep(3000);

            subscriber.onNext("" + Integer.valueOf(mEditTextValueToProcess.getText().toString()) * 10);
            subscriber.onCompleted();
        }
    });

}

private void intiViews() {
    mEditTextValueToProcess = (EditText) findViewById(R.id.edittext);
    mButtonGoAsynchronous = (Button) findViewById(R.id.button_go_asynchronous);
    mTextViewProcessedValue = (TextView) findViewById(R.id.textview_processed_value);
    //mProgressBar = (ProgressBar) findViewById(R.id.progressDialog);

    mButtonGoAsynchronous.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mAsyncObservable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(mAsyncSubscriber);
        }
    });
}

}

【问题讨论】:

  • Rx-java2 标签,而仅使用 Rxjava1? :)
  • 在 mAsyncSubscriber 中覆盖 onStart 并使您的进度条在那里可见。因为当你在做subscribeOn(Schedulers.io()) 时,observable 中的代码将在另一个线程上执行,然后是你的 UI 线程

标签: android android-asynctask rx-java rx-android


【解决方案1】:

你试过了吗

private Observable<String> createObservable(final int number) { 
     return rx.Observable.create(new rx.Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            SystemClock.sleep(3000);

            subscriber.onNext("" + number  * 10);
            subscriber.onCompleted();
        }
    });
}

private void intiViews() {
    mEditTextValueToProcess = (EditText) findViewById(R.id.edittext);
    mButtonGoAsynchronous = (Button) findViewById(R.id.button_go_asynchronous);
    mTextViewProcessedValue = (TextView) findViewById(R.id.textview_processed_value);
    mProgressBar = (ProgressBar) findViewById(R.id.progressDialog);

    mButtonGoAsynchronous.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mProgressBar.setVisibility(View.VISIBLE);
            createObservable(Integer.valueOf(mEditTextValueToProcess.getText().toString()))
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext((ignored) -> {
                         mProgressBar.setVisibility(View.GONE);
                    })
                    .subscribe(mAsyncSubscriber);
        }
    });
}

?

【讨论】:

  • 我喜欢您发布的代码风格..但是请您告诉我(忽略)-> 是什么意思??
  • 这是一个 lambda 表达式,通过添加 Retrolambda 或更新到 android studio 3.0.0 来支持
  • 这是一个输入参数,与调用该方法无关
【解决方案2】:

你需要改变一些事情来实现这一点。看mAsyncSubscriber初始化,onStart()方法&progressBar初始化。您收到错误的原因是您正在初始化并使进度条在另一个线程中可见,然后是您的 UI 线程(因为您指定了这个 -> subscribeOn(Schedulers.io())。

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();
private EditText mEditTextValueToProcess = null;
private Button mButtonGoAsynchronous = null;
private TextView mTextViewProcessedValue = null;
private ProgressBar mProgressBar = null;
private rx.Observable<String> mAsyncObservable = null;
Subscriber mAsyncSubscriber;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    intiViews();

   mAsyncSubscriber = new Subscriber<String>() {

   // Override onStart method
   @Override
   public void onStart() {
        mProgressBar.setVisibility(View.VISIBLE);
   }

    @Override
    public void onCompleted() {
        Log.w(TAG, "onCompleted");
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void onError(Throwable e) {
        Log.w(TAG, "onError: " + e.getMessage().toString());
        mProgressBar.setVisibility(View.GONE);
    }

    @Override
    public void onNext(String o) {
        Log.w(TAG, "onNext:->after processing " + o);
        mTextViewProcessedValue.setText(o);
    }
};


    mAsyncObservable = rx.Observable.create(new rx.Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {

            SystemClock.sleep(3000);

            subscriber.onNext("" + Integer.valueOf(mEditTextValueToProcess.getText().toString()) * 10);
            subscriber.onCompleted();
        }
    });

}

private void intiViews() {
    // Init your progressbar
    mProgressBar = (ProgressBar) findViewById(R.id.progressDialog);
    mEditTextValueToProcess = (EditText) findViewById(R.id.edittext);
    mButtonGoAsynchronous = (Button) findViewById(R.id.button_go_asynchronous);
    mTextViewProcessedValue = (TextView) findViewById(R.id.textview_processed_value);
    //mProgressBar = (ProgressBar) findViewById(R.id.progressDialog);

    mButtonGoAsynchronous.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mAsyncObservable.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(mAsyncSubscriber);
        }
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    相关资源
    最近更新 更多