2016-06-08 107 views
2

我是Android開發的新手,我嘗試使用服務和intentservice獲得一些練習。服務和intentservice之間的溝通

這是我的服務類:

public class MyBaseService extends Service { 

private double[] returnData; 

public MyBaseService() { 
} 

@Override 
public void onCreate() { 
    returnData = new double[//dataSise]; 
} 

/** The service is starting, due to a call to startService() */ 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    try { 
     for (Map.Entry<Integer, Double[]> mapEntry : dataMap.entrySet()) { 

      doXYZ(mapEntry.getValue()); 
      Arrays.sort(returnData); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    Intent intents = new Intent(); 
    intents.setAction(ACTION_SEND_TO_ACTIVITY); 
    sendBroadcast(intents); 
    return START_STICKY; 
} 

/** A client is binding to the service with bindService() */ 
@Override 
public IBinder onBind(Intent arg0) { 
    return mBinder; 
} 

public class MyBinder extends Binder { 
    public MyBaseService getService() { 
     return MyBaseService.this; 
    } 
} 

/** Called when a client is binding to the service with bindService()*/ 
@Override 
public void onRebind(Intent intent) { 

} 

/** Called when The service is no longer used and is being destroyed */ 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
} 


private void doXYZ(double[] data) { 
    int gallerySize = galleryFiles.length; 

    for (int i=0; i<data.length; ++i) { 
     Intent cfIntent = new Intent(this, MyIntentService.class); 
     compareFeatureIntent.putExtra(MyIntentService.COMPARING_INDEX, i); 
     startService(cfIntent); 
    } 

} 

BroadcastReceiver mReceiver; 

// use this as an inner class like here or as a top-level class 
public class MyReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     int index = intent.getIntExtra(MyIntentService.COMPARING_INDEX, 0); 
     double scores = intent.getDoubleArrayExtra(MyIntentService.COMPARING_SCORE); 
     data[index] = scores[0]; 
    } 

    // constructor 
    public MyReceiver(){ 
    } 
} 

}

這是intentservice類:

public class MyIntentService extends IntentService { 
protected static final String ACTION_COMPARE_FEATURES = "CompareFeatures"; 
protected static final String COMPARING_SCORE = "Score"; 
protected static final String COMPARING_INDEX = "Index"; 

public MyIntentService() { 
    super("MyIntentService"); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    int index = (int)intent.getLongExtra(COMPARING_INDEX, 0); 

    // This is long operation 
    double[] scores = getScores(index); 

    Intent intents = new Intent(); 
    intents.setAction(ACTION_COMPARE_FEATURES); 
    intent.putExtra(COMPARING_SCORE, scores); 
    intent.putExtra(COMPARING_INDEX, index); 
    sendBroadcast(intents); 
} 

}

的情況是,我要開始MyBaseService類主要活動內部。在MyBaseService裏面,我需要做一個長時間運行的操作,並且需要多次迭代該操作。所以,我把這個長操作放在MyIntentService中,然後在一個循環中啓動MyIntentService。

MyIntentService會產生一些數據,我想在MyBaseService類中獲取這些數據來做一些進一步的操作。

問題我正面臨與MyBaseService和MyIntentService之間的通信。因爲MyBaseService會多次啓動MyIntentSerice,所以我最初的解決方案是從MyIntentService中sendBroadcast(),並在MyBaseService中註冊接收者。

所以,我的問題是:

  1. 是我與MyBaseService MyIntentService設計效率?如果不是,我應該如何將我想要的結果歸檔?

  2. 如果sendBroadcast()是一個正確的方向,我應該如何在MyBaseService中註冊?

回答

1

你的建築很好。有幾種方法可以做到這一點,但這種方法是可以的。

您可以在MyBaseSerice.onStartCommand()中註冊BroadcastReceiver,並在MyBaseService.onDestroy()中取消其註冊。您需要確定如何關機。要麼Activity可以這樣做,要麼MyBaseService將需要跟蹤從IntentService等待的回覆數量,只要它獲得最後一個回覆,就可以通過調用stopSelf()來關閉它。