簡體   English   中英

如何用RxAndroid替換AsyncTask

[英]how to replace AsyncTask by RxAndroid

我正在嘗試使用RxAndroid來完成AsyncTask所做的相同工作。 我編寫了一個簡單的示例,在其中我在edittext中輸入一個整數,然后當我按下按鈕時,使用“ SystemClock.sleep”使讀取進入睡眠狀態3秒鍾,而在線程處於睡眠狀態時,我會顯示一個進度條,當三個幾秒鍾后,進度條將消失,在編輯文本中輸入的值將乘以10,並顯示在文本視圖中。

通常,當我使用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);
        }
    });
}

}

你有沒有嘗試過

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

您只需要做一些更改即可實現此目的。 查看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);
        }
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM