2016-01-31 98 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

希望這會有所幫助。