You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android原生如何运行多个URL连接?含双连接代码示例

嘿,我来帮你搞定Android原生环境下多网络连接的实现问题!看你现在用的是AsyncTask,先给你提个醒:AsyncTask在API 30之后已经被标记为废弃了,不过我会先基于你现有的代码逻辑调整,同时也会给你推荐更现代的替代方案,方便你后续选择。


方案一:基于现有AsyncTask的改造

你当前的代码是用单个AsyncTask处理一个请求,要同时跑两个网络连接,有两种常见思路:

1. 启动两个独立的AsyncTask实例

把AsyncTask改成通用模板,通过构造函数传入目标URL和对应的UI控件,这样就能复用同一个类处理不同请求,并行执行两个任务:

public class MyPublicClass extends AppCompatActivity {
    private TextView mytxtview1;
    private TextView mytxtview2;
    private ProgressDialog progress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mytxtview1 = findViewById(R.id.txt_view_1);
        mytxtview2 = findViewById(R.id.txt_view_2);
        progress = new ProgressDialog(this);
        progress.setMessage("加载中...");
        progress.show();

        // 启动第一个网络请求
        new NetworkTask("url1", mytxtview1).execute();
        // 启动第二个网络请求
        new NetworkTask("url2", mytxtview2).execute();
    }

    // 通用网络请求AsyncTask子类
    private class NetworkTask extends AsyncTask<String, Void, String> {
        private String targetUrl;
        private TextView targetTextView;

        public NetworkTask(String url, TextView textView) {
            this.targetUrl = url;
            this.targetTextView = textView;
        }

        @Override
        protected String doInBackground(String... params) {
            StringBuilder output = new StringBuilder();
            try {
                URL url = new URL(targetUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line);
                }
                reader.close();
                connection.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
                return "请求失败:" + e.getMessage();
            }
            return output.toString();
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // onPostExecute本身就在主线程,无需额外调用runOnUiThread
            targetTextView.setText(result);
            // 检查两个请求是否都完成,完成后关闭进度条
            if (!TextUtils.isEmpty(mytxtview1.getText()) && !TextUtils.isEmpty(mytxtview2.getText())) {
                if (progress.isShowing()) progress.dismiss();
            }
        }
    }
}

2. 在单个AsyncTask里串行处理两个请求

如果需要两个请求按顺序执行(比如第一个请求完成后再执行第二个),可以把网络请求逻辑抽取成独立方法,在doInBackground里依次调用:

private class SerialNetworkTask extends AsyncTask<Void, Void, String[]> {
    @Override
    protected String[] doInBackground(Void... voids) {
        String[] results = new String[2];
        // 串行执行两个请求
        results[0] = fetchData("url1");
        results[1] = fetchData("url2");
        return results;
    }

    @Override
    protected void onPostExecute(String[] results) {
        super.onPostExecute(results);
        mytxtview1.setText(results[0]);
        mytxtview2.setText(results[1]);
        if (progress.isShowing()) progress.dismiss();
    }

    // 通用网络请求方法
    private String fetchData(String urlStr) {
        StringBuilder output = new StringBuilder();
        try {
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line);
            }
            reader.close();
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            return "请求失败:" + e.getMessage();
        }
        return output.toString();
    }
}

启动这个任务只需要一行代码:new SerialNetworkTask().execute();


方案二:更现代的替代方案(推荐)

由于AsyncTask已被废弃,Android官方推荐使用Coroutines(协程)或OkHttp来处理网络请求,代码更简洁,也能避免AsyncTask的潜在问题(比如内存泄漏、配置变更异常)。

用Coroutines实现并行请求

先在项目的build.gradle中添加协程依赖:

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}

然后用Kotlin协程实现并行请求(如果是Java项目,也可以使用协程的Java API,不过Kotlin写法更简洁):

class MyPublicClass : AppCompatActivity() {
    private lateinit var mytxtview1: TextView
    private lateinit var mytxtview2: TextView
    private lateinit var progress: ProgressDialog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        mytxtview1 = findViewById(R.id.txt_view_1)
        mytxtview2 = findViewById(R.id.txt_view_2)
        progress = ProgressDialog(this).apply {
            setMessage("加载中...")
            show()
        }

        // 启动协程,绑定生命周期避免内存泄漏
        lifecycleScope.launch {
            // 并行执行两个请求
            val result1 = async { fetchData("url1") }
            val result2 = async { fetchData("url2") }

            // 等待两个请求都完成
            val data1 = result1.await()
            val data2 = result2.await()

            // 更新UI
            mytxtview1.text = data1
            mytxtview2.text = data2
            if (progress.isShowing) progress.dismiss()
        }
    }

    // 挂起函数,在IO线程执行网络请求
    private suspend fun fetchData(urlStr: String): String {
        return withContext(Dispatchers.IO) {
            val output = StringBuilder()
            try {
                val url = URL(urlStr)
                val connection = url.openConnection() as HttpURLConnection
                connection.requestMethod = "GET"
                
                val reader = BufferedReader(InputStreamReader(connection.inputStream))
                var line: String?
                while (reader.readLine().also { line = it } != null) {
                    output.append(line)
                }
                reader.close()
                connection.disconnect()
            } catch (e: Exception) {
                e.printStackTrace()
                return@withContext "请求失败:${e.message}"
            }
            output.toString()
        }
    }
}

用OkHttp实现并行请求

先添加OkHttp依赖:

dependencies {
    implementation "com.squareup.okhttp3:okhttp:4.11.0"
}

然后编写代码:

public class MyPublicClass extends AppCompatActivity {
    private TextView mytxtview1;
    private TextView mytxtview2;
    private ProgressDialog progress;
    private OkHttpClient client = new OkHttpClient();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mytxtview1 = findViewById(R.id.txt_view_1);
        mytxtview2 = findViewById(R.id.txt_view_2);
        progress = new ProgressDialog(this);
        progress.setMessage("加载中...");
        progress.show();

        // 第一个请求
        Request request1 = new Request.Builder().url("url1").build();
        client.newCall(request1).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(() -> {
                    mytxtview1.setText("请求失败:" + e.getMessage());
                    checkIfAllDone();
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    String data = response.body().string();
                    runOnUiThread(() -> {
                        mytxtview1.setText(data);
                        checkIfAllDone();
                    });
                } else {
                    runOnUiThread(() -> {
                        mytxtview1.setText("请求失败:" + response.code());
                        checkIfAllDone();
                    });
                }
            }
        });

        // 第二个请求
        Request request2 = new Request.Builder().url("url2").build();
        client.newCall(request2).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(() -> {
                    mytxtview2.setText("请求失败:" + e.getMessage());
                    checkIfAllDone();
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    String data = response.body().string();
                    runOnUiThread(() -> {
                        mytxtview2.setText(data);
                        checkIfAllDone();
                    });
                } else {
                    runOnUiThread(() -> {
                        mytxtview2.setText("请求失败:" + response.code());
                        checkIfAllDone();
                    });
                }
            }
        });
    }

    // 检查两个请求是否都完成,关闭进度条
    private void checkIfAllDone() {
        if (!TextUtils.isEmpty(mytxtview1.getText()) && !TextUtils.isEmpty(mytxtview2.getText())) {
            if (progress.isShowing()) progress.dismiss();
        }
    }
}

必加的注意事项

  • 网络权限:别忘了在AndroidManifest.xml中添加网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • UI线程限制:所有更新UI的操作必须在主线程执行,上述方案中已经通过onPostExecute、lifecycleScope、runOnUiThread保证了这一点。

内容的提问来源于stack exchange,提问作者betty bth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:34:16