2016-01-31 72 views
3

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

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

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

希望这会有所帮助。