android - 在单个服务中处理多个网络调用

标签 android android-asynctask

我在我的服务中使用了一个 AsyncTask,所以我可以调用多个 url。我不确定如何在单个服务中处理调用 url。这是我目前的解决方案:

public int onStartCommand(Intent intent, int flags, int startId) { SharedPreferences 首选项 = getSharedPreferences("data", MODE_PRIVATE); String apiKey = preferences.getString("apiKey", null); FetchData 数据 = new FetchData(); data.execute("旅行", apiKey); FetchData otherData = new FetchData(); otherData.execute("通知",apiKey); FetchData barData = new FetchData(); barData.execute("bars", apiKey); 检查数据(); 返回START_STICKY; } 这是我调用不同 url 的 ASyncTask doInBackgroud:

protected String[] doInBackground(String... params) {
        HttpURLConnection urlConnection = null;
        BufferedReader reader= null;
        String data = null;


        try {
            selection = params[0];

            //url for the data fetch
            URL url = new URL("http://api.torn.com/user/?selections="+selection+"&key=*****");

            //gets the http result
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            //reads the data into an input file...maybe
            InputStream inputStream = urlConnection.getInputStream();
            StringBuilder buffer = new StringBuilder();
            if (inputStream == null) {
                return null;
            }

            //does something important
            reader = new BufferedReader(new InputStreamReader(inputStream));

            //reads the reader up above
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line).append("\n");
            }

            if (buffer.length() == 0) {
                return null;
            }

            data = buffer.toString();
        } catch (IOException e) {
            return null;
        }
        finally{
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException ignored) {
                }
            }
        }

我什至不确定我是否应该在服务中使用 ASyncTask。谁能告诉我处理这种情况的正确方法是什么

最佳答案

您不需要实现 AsyncTask。您应该创建一个扩展 Service 的类,该类将处理它自己的消息队列并为它接收的每条消息创建一个单独的线程。例如:

public class MyNetworkService extends Service {
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;

    // Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            // Obtain your url from your data bundle, passed from the start intent.
            Bundle data = msg.getData();

            // Get your url string and api key.
            String action = data.getString("action");
            String apiKey = data.getString("apiKey");

            //
            //
            // Open your connection here.
            //
            //

            // Stop the service using the startId, so that we don't stop
            // the service in the middle of handling another job
            stopSelf(msg.arg1);
        }
    }

    @Override
    public void onCreate() {
        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        HandlerThread thread = new HandlerThread("ServiceStartArguments",
                 Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();

        // Get the HandlerThread's Looper and use it for our Handler
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

        // Retrieve your bundle from your intent.
        Bundle data = intent.getExtras();

        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;

        // Set the message data as your intent bundle.
        msg.setData(data);

        mServiceHandler.sendMessage(msg);

        // If we get killed, after returning from here, restart
        return START_STICKY;
    }
}

设置服务后,您可以在 list 中定义该服务。

<service android:name=".MyNetworkService" />

例如,在您的 Activity 中,或您认为有必要的任何地方,您可以使用 startService() 启动服务。

// Create the intent.
Intent travelServiceIntent = new Intent(this, MyNetworkService.class);

// Create the bundle to pass to the service.
Bundle data = new Bundle();
data.putString("action", "travel");
data.putString("apiKey", apiKey);

// Add the bundle to the intent.
travelServiceIntent.putExtras(data);

// Start the service.
startService(travelServiceIntent); // Call this for each URL connection you make.

如果你想绑定(bind)服务并从 UI 线程与之通信,你需要实现一个 IBinder 接口(interface)并调用 bindService() 而不是 startService() .

查看 Bound Services .

希望这对您有所帮助。

关于android - 在单个服务中处理多个网络调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35118098/

相关文章:

java - 减少应用程序传送的 Realm 数据库的大小

android - 渲染索引三角形在 Opengl ES 2.0 的跟踪器中显示模式 GL_MAP_INVALIDATE_RANGE_BIT

android - `doInBackground()` 不接受类型为 void 的 `AsyncTask`?

java - 当AsyncTasks满了会发生什么?

java - Android Java - ThreadPoolExecutor$AbortPolicy

java - 在 AsyncTask 中填充数组时出现 Android 错误

android - 如何在android中制作通话记录应用程序

android - 无法在 android 中使用 intent 打开 Linkedin 配置文件

安卓 ListFragment : How to enable the Lollipop "Ripple Effect"?

android - 我需要知道已经上传了多少字节来更新进度条android