service和intentservice之间的通信
Communication between service and intentservice
我是 Android 开发的新手,我尝试对 service 和 intentservice 进行一些练习。
这是我的服务class:
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 class:
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);
}
}
场景是我想在 main activity 中启动 MyBaseService class。在 MyBaseService 内部,我需要做一个很长的 运行 操作,并且需要多次迭代该操作。所以,我把那个长操作放在 MyIntentService 中,然后循环启动 MyIntentService。
MyIntentService 会产生一些数据,我想在 MyBaseService class 中取回这些数据以做一些进一步的操作。
我在 MyBaseService 和 MyIntentService 之间的通信中遇到的问题。因为MyBaseService会多次启动MyIntentSerice,我最初的解决方案是从MyIntentService中调用sendBroadcast(),在MyBaseService中注册receiver。
那么,我的问题是:
我使用 MyBaseService MyIntentService 的设计是否高效?如果没有,我应该怎么做才能得到我想要的结果?
如果sendBroadcast()是一个正确的方向,我应该如何注册MyBaseService?
您的架构很好。有几种方法可以做到这一点,但这种方法是可行的。
您可以在 MyBaseSerice.onStartCommand()
中注册 BroadcastReceiver
并在 MyBaseService.onDestroy()
中取消注册。
您将需要确定如何关闭 MyBaseService
。 Activity
可以做到,或者 MyBaseService
需要跟踪它正在等待 IntentService
的回复数量,一旦它得到最后一个回复,它就可以自行关闭通过调用 stopSelf()
.
我是 Android 开发的新手,我尝试对 service 和 intentservice 进行一些练习。
这是我的服务class:
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 class:
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);
}
}
场景是我想在 main activity 中启动 MyBaseService class。在 MyBaseService 内部,我需要做一个很长的 运行 操作,并且需要多次迭代该操作。所以,我把那个长操作放在 MyIntentService 中,然后循环启动 MyIntentService。
MyIntentService 会产生一些数据,我想在 MyBaseService class 中取回这些数据以做一些进一步的操作。
我在 MyBaseService 和 MyIntentService 之间的通信中遇到的问题。因为MyBaseService会多次启动MyIntentSerice,我最初的解决方案是从MyIntentService中调用sendBroadcast(),在MyBaseService中注册receiver。
那么,我的问题是:
我使用 MyBaseService MyIntentService 的设计是否高效?如果没有,我应该怎么做才能得到我想要的结果?
如果sendBroadcast()是一个正确的方向,我应该如何注册MyBaseService?
您的架构很好。有几种方法可以做到这一点,但这种方法是可行的。
您可以在 MyBaseSerice.onStartCommand()
中注册 BroadcastReceiver
并在 MyBaseService.onDestroy()
中取消注册。
您将需要确定如何关闭 MyBaseService
。 Activity
可以做到,或者 MyBaseService
需要跟踪它正在等待 IntentService
的回复数量,一旦它得到最后一个回复,它就可以自行关闭通过调用 stopSelf()
.