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()来关闭它。