在单个服务中处理多个网络呼叫

时间:2016-01-31 19:07:50

标签: android android-asynctask

我在我的服务中使用AsyncTask,所以我可以调用多个网址。我不知道如何在一个服务中处理呼叫网址。这是我目前的解决方案:

public int onStartCommand(Intent intent, int flags, int startId) { SharedPreferences preferences = getSharedPreferences("data", MODE_PRIVATE); String apiKey = preferences.getString("apiKey", null); FetchData data = new FetchData(); data.execute("travel", apiKey); FetchData otherData = new FetchData(); otherData.execute("notifications",apiKey); FetchData barData = new FetchData(); barData.execute("bars", apiKey); checkData(); return START_STICKY; } 这是我的ASyncTask doInBackgroud调用不同的URL:

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。任何人都可以告诉我处理这种情况的正确方法

1 个答案:

答案 0 :(得分:1)

您不需要实施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;
    }
}

设置完服务后,您可以在清单中定义该服务。

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

在您的活动中,或者您认为有必要的任何地方,您可以使用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.

如果要绑定服务并从UI线程与其进行通信,则需要实现IBinder接口并调用bindService()而不是startService()

查看Bound Services

希望这有帮助。