尝试启动IntentService结果“RuntimeException:将结果传递给活动失败”

时间:2016-02-28 09:56:03

标签: android service intentservice

我正在尝试使用服务( MainService.class )来启动intentService( ConnectToServerIntentService.class )并导致如上所述的RuntimeException。当向 ConnectToServerIntentService.class 提交意图时,错误会出现在 MainService.class sendRequestToServer()方法中。

代码

MainService.class:

complete <-function(directory,id){
  filenames <-sprintf("%03d.csv", id)
  filenames <-paste(directory,filenames,sep = '/')
  dataframe <-data.frame(id=numeric(0),nobs=numeric(0))
  for(i in filenames){
    data <- read.csv(i)
    dataframe[i,dataframe$id]<-data[data$id]
    dataframe[i,dataframe$nobs]<-nrow(data[!is.na(data$sulfate & data$nitrate),])
  }

  dataframe

}

}

ConnectToServerIntentService.class

public class MainService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{

@Override
public void onCreate() {
    super.onCreate();
    createGoogleApiClient();
    connectGoogleApiClient();
}

@Override
public void onDestroy() {
    super.onDestroy();
    LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
    disconnectGoogleApiClient();
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

private static GoogleApiClient googleApiClient;

private void createGoogleApiClient(){
    googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
}

private void connectGoogleApiClient(){
    if(!googleApiClient.isConnected()){
        googleApiClient.connect();
    }
}

private void disconnectGoogleApiClient(){
    if(googleApiClient.isConnected()){
        googleApiClient.disconnect();
    }
}

private final static long LOCATION_INTERVAL=30*60*1000;
private final static long LOCATION_FASTEST_INTERVAL=30*60*1000;

@Override
public void onConnected(Bundle bundle) {
    System.out.println("GoogleApiClient onConnected");
    LocationRequest locationRequest=LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(LOCATION_INTERVAL);
    locationRequest.setFastestInterval(LOCATION_FASTEST_INTERVAL);
    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {
    System.out.println("GoogleApiClient onConnectionSuspended");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    System.out.println("GoogleApiClient onConnectionFailed");
    System.out.println(connectionResult.getErrorMessage());
}

static Location currentLocation;
private final static String URL="http://225.225.225.225/PM25Predictor_beta/Reciever.jsp";

@Override
public void onLocationChanged(Location location) {
    if(location!=null){
        currentLocation=location;
    }else{
        currentLocation=LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    }

    if(currentLocation!=null){
        sendRequestToServer(currentLocation.getLatitude()+","+currentLocation.getLongitude(),candidateStationLatLng);
    }else{
        sendRequestToServer(null,candidateStationLatLng);
    }
}

private void sendRequestToServer(String currentStationLatLng, String[] candidateStationLatLng){
    String currentStationData="CURRENT_STATION_DATA:"+currentStationLatLng;
    ArrayList<String> requestDataSet_al=new ArrayList<>();
    requestDataSet_al.add(URL);
    requestDataSet_al.add(currentStationData);
    if(candidateStationLatLng!=null){
        String[] candidateStationData=new String[candidateStationLatLng.length];
        for(int i=0; i<candidateStationLatLng.length; i++){
            candidateStationData[i]="CANDIDATE_STATION_DATA:"+candidateStationLatLng[i];
        }
        requestDataSet_al.addAll(Arrays.asList(candidateStationData));
    }

    for(int i=0; i<requestDataSet_al.size(); i++){
        System.out.println(requestDataSet_al.get(i));
    }

    Intent requestIntent=new Intent(this,ConnectToServerIntentService.class);
    Bundle requestBundle=new Bundle();
    requestBundle.putStringArray("CONNECT_TO_SERVER_REQUEST", requestDataSet_al.toArray(new String[requestDataSet_al.size()]));
    requestIntent.putExtras(requestBundle);
    startService(requestIntent);

    long updateTime=System.currentTimeMillis();
    Intent timerIntent=new Intent(this,TimerIntentService.class);
    Bundle timerBundle=new Bundle();
    timerBundle.putLong("UPDATE_TIME", updateTime);
    timerIntent.putExtras(timerBundle);
    startService(timerIntent);*//the problem is there.*
}

String[] candidateStationLatLng;
public void submitRequest(String[] checkedCity){
    candidateStationLatLng=new String[checkedCity.length];
    for(int i=0; i<candidateStationLatLng.length; i++){
        candidateStationLatLng[i]=checkedCity[i].split(",")[2]+","+checkedCity[i].split(",")[3];
    }
    onLocationChanged(currentLocation);
}

}

错误讯息:

public class ConnectToServerIntentService extends IntentService {

public static final String CONNECT_TO_SERVER_INTENT_SERVICE_ACTION="CONNECT_TO_SERVER_INTENT_SERVICE_ACTION";

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


@Override
public void onDestroy() {
    System.out.println("ConnectToServerIntentService on Destroy!");
    super.onDestroy();
}

@Override
protected void onHandleIntent(Intent intent) {
    String connectToServerResponse=connectToServer(intent.getExtras().getStringArray("CONNECT_TO_SERVER_REQUEST"));
    if(connectToServerResponse!=null){
        Intent responseIntent=new Intent(CONNECT_TO_SERVER_INTENT_SERVICE_ACTION);
        Bundle responseBundle=new Bundle();
        responseBundle.putString("CONNECT_TO_SERVER_RESPONSE",connectToServerResponse);
        responseIntent.putExtras(responseBundle);
        sendBroadcast(responseIntent);
    }
}

private String connectToServer(String... params){
    try{
        URL url=new URL(params[0]);

        ArrayList<String> stationLatLng_al=new ArrayList<>();
        stationLatLng_al.addAll(Arrays.asList(params));

        stationLatLng_al.trimToSize();
        String[] stationLatLng=new String[stationLatLng_al.size()];
        stationLatLng_al.toArray(stationLatLng);

        HttpURLConnection urlConnection= (HttpURLConnection) url.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setRequestMethod("POST");

        OutputStream out=new BufferedOutputStream(urlConnection.getOutputStream());
        out.write(getPostData(stationLatLng).getBytes("utf-8"));

        out.flush();
        out.close();

        int responseCode=urlConnection.getResponseCode();
        if(responseCode==200){
            System.out.println("Connection done.");
            return getStringFromInputStream(urlConnection.getInputStream());
        }else{
            System.out.println("Connection fail!");
            return null;
        }

    }catch(Exception ex){
        ex.printStackTrace();
    }
    return null;
}

private static String getPostData(String[] stationLatLng){
    String result=null;

    for(int i=0; i<stationLatLng.length; i++){
        if(i==0){
            result=stationLatLng[i].split(":")[0]+"="+stationLatLng[i].split(":")[1];
        }else{
            result=result+"&"+stationLatLng[i].split(":")[0]+"="+stationLatLng[i].split(":")[1];
        }
    }
    return result;
}

private static String getStringFromInputStream(InputStream in) throws IOException {
    ByteArrayOutputStream out=new ByteArrayOutputStream();
    byte[] buffer=new byte[1024];
    int len;
    while((len=in.read(buffer))!=-1){
        out.write(buffer, 0, len);
    }
    in.close();
    String result=out.toString("utf-8");
    out.close();
    return result;
}

错误消息中的System.out.println()包含requestDataSet_al(MainService.class-&gt; sendRequestToServer),因此我认为这不是bundle的问题。 任何解决方案都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

我没有完全测试您的代码,但我的建议是覆盖onStartCommand类中的ConnectToServerIntentService

根据Documentation 每次客户端通过调用startService(Intent)显式启动服务,系统调用它,提供它提供的参数和表示启动请求的唯一整数标记。

建议在onStartCommand中的IntentService方法中放置创建逻辑。它看起来像这样

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
   //Add your onCreate Logic here
    return START_STICKY;
}