【问题标题】:Convert AsyncTask to RxJava将 AsyncTask 转换为 RxJava
【发布时间】:2026-02-06 19:40:01
【问题描述】:

对 Rx 有点陌生,所以我正在寻找一些关于将以下 AsyncTask 转换为 Rx 的帮助,希望这样我可以使用我已经知道可以做某事的代码来更多地可视化 Rx。我发现了一些其他一些有点相关的 SO 答案,但其中很多都不是网络请求,而且许多人使用不同的运营商来获得不同的答案,所以有点困惑。

这是 AsyncTask:

这是我的 WhatsTheWeather 应用程序的 Java 代码(包括 MainActivity 中的所有代码):

public class MainActivity extends AppCompatActivity {

EditText cityName;
TextView resultTextview;

public void findTheWeather(View view){
    Log.i("cityName", cityName.getText().toString());

    InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    mgr.hideSoftInputFromWindow(cityName.getWindowToken(), 0);

    try {
        String encodedCityName = URLEncoder.encode(cityName.getText().toString(), "UTF-8");
        DownLoadTask task = new DownLoadTask();
        task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + cityName.getText().toString() + "&appid=a018fc93d922df2c6ae89882e744e32b");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
    }
}


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

    cityName = (EditText)findViewById(R.id.cityName);
    resultTextview = (TextView) findViewById(R.id.resultTextView);

}


public class DownLoadTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {
        String result = "";
        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL(urls[0]);
            urlConnection = (HttpURLConnection)url.openConnection();

            InputStream inputStream = urlConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(inputStream);

            int data = reader.read();
            while(data != -1){
                char current = (char) data;
                result +=current;
                data = reader.read();
            }
            return result;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        try {
            String message = "";
            JSONObject jsonObject = new JSONObject(result);

            String weatherInfo = jsonObject.getString("weather");
            Log.i("Weather content", weatherInfo);
            JSONArray arr = new JSONArray(weatherInfo);

            for(int i=0; i<arr.length(); i++){
                JSONObject jsonPart = arr.getJSONObject(i);

                String main = "";
                String description="";

                main = jsonPart.getString("main");
                description = jsonPart.getString("description");

                if(main != "" && description != ""){
                    message += main + ": "+ description + "\r\n"; //for a line break
                }

            }

            if (message != ""){
                resultTextview.setText(message);
            } else {
                Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
            }
        } catch (JSONException e) {
            Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
        }
    }
}

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 如果代码块被组织在一起,您的问题会更容易阅读,并且您的实际问题不会被分成块引号。 Markdown help 文档演示了如何执行此操作。

标签: android android-asynctask rx-java


【解决方案1】:

试试这个。

public void networkCall(final String urls) {
    Observable.fromCallable(new Func0<String>() {
        @Override
        public String call() {
            String result = "";
            URL url = null;
            HttpURLConnection urlConnection = null;
            try {
                url = new URL(urls);
                urlConnection = (HttpURLConnection) url.openConnection();

                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);

                int data = reader.read();

                while (data != -1) {
                    char current = (char) data;
                    result += current;
                    data = reader.read();
                }

                try {
                    String message = "";
                    JSONObject jsonObject = new JSONObject(result);

                    String weatherInfo = jsonObject.getString("weather");
                    Log.i("Weather content", weatherInfo);
                    JSONArray arr = new JSONArray(weatherInfo);

                    for (int i = 0; i < arr.length(); i++) {
                        JSONObject jsonPart = arr.getJSONObject(i);

                        String main = "";
                        String description = "";

                        main = jsonPart.getString("main");
                        description = jsonPart.getString("description");

                        if (main != "" && description != "") {
                            message += main + ": " + description + "\r\n"; //for a line break
                        }

                    }

                    return message;

                } catch (JSONException e) {
                    Toast.makeText(getApplicationContext(), "Could not find weather", Toast.LENGTH_LONG).show();
                }


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<String>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(String message) {
            if (message != ""){
                resultTextview.setText(message);
            } else {
                Toast.makeText(getApplicationContext(),"Could not find weather",Toast.LENGTH_LONG).show();
            }
        }
    });
}

但是,我建议同时使用 Retrofit 和 RxJava。

【讨论】:

    【解决方案2】:

    在集成 Retrofit 之前,您应该了解几件事。

    • 尽量不要使用旧版本的Retrofit
    • Retrofit2 是您当前应该使用的那个
    • 尽量避免RetrofitRxJavaRxAndroid 的代码集成 目前(对于初学者来说太复杂了)
    • 确保您也熟悉GSONJackson
    • HttpClient 折旧,而OkHttpHttpUrlConnection 相对快,Retrofit2 通常使用
    • 最后,这里是 Retrofit2 的 link。它非常详细且易于理解。杰克·沃顿 (Jack Wharton) 已尽力使其尽可能简单易懂。

    【讨论】:

    • 感谢@crickrt_007 的评论。我做了一些修改。