2016-02-28 52 views
1

我试图使用服务(MainService.class)启动一个intentService(ConnectToServerIntentService.class),并导致一个RuntimeException如前所述。错误出现在方法sendRequestToServer() at MainService.class当提交意向ConnectToServerIntentService.class尝试启动IntentService结果“的RuntimeException:不提供结果的活动”

代码

MainService.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); 
} 

}

ConnectToServerIntentService.class

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; 
} 

}

错误消息:

02-28 17:16:25.882 9227-9227/com.example.user.pm25predictortest I/System.out: http://225.225.225.225/PM25Predictor_beta/Reciever.jsp 
02-28 17:16:25.882 9227-9227/com.example.user.pm25predictortest I/System.out: CURRENT_STATION_DATA:22.6412969,120.5964363 
02-28 17:16:25.882 9227-9227/com.example.user.pm25predictortest I/System.out: CANDIDATE_STATION_DATA:24.8238676,120.9474747 
02-28 17:16:25.882 9227-9227/com.example.user.pm25predictortest I/System.out: CANDIDATE_STATION_DATA:24.7920604,120.9933678 
02-28 17:16:25.882 9227-9227/com.example.user.pm25predictortest D/AndroidRuntime: Shutting down VM 
02-28 17:16:25.892 9227-9227/com.example.user.pm25predictortest E/AndroidRuntime: FATAL EXCEPTION: main 
                        Process: com.example.user.pm25predictortest, PID: 9227 
                        java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { cmp=com.example.user.pm25predictortest/.MainActivity (has extras) }} to activity {com.example.user.pm25predictortest/com.example.user.pm25predictortest.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.Context.startService(android.content.Intent)' on a null object reference 
                         at android.app.ActivityThread.deliverResults(ActivityThread.java:3558) 
                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:3601) 
                         at android.app.ActivityThread.access$1300(ActivityThread.java:147) 
                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1333) 
                         at android.os.Handler.dispatchMessage(Handler.java:102) 
                         at android.os.Looper.loop(Looper.java:135) 
                         at android.app.ActivityThread.main(ActivityThread.java:5257) 
                         at java.lang.reflect.Method.invoke(Native Method) 
                         at java.lang.reflect.Method.invoke(Method.java:372) 
                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:921) 
                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:716) 
                        Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ComponentName android.content.Context.startService(android.content.Intent)' on a null object reference 
                         at android.content.ContextWrapper.startService(ContextWrapper.java:522) 
                         at com.example.user.pm25predictortest.MainService.sendRequestToServer(MainService.java:129) 
                         at com.example.user.pm25predictortest.MainService.onLocationChanged(MainService.java:102) 
                         at com.example.user.pm25predictortest.MainService.submitRequest(MainService.java:145) 
                         at com.example.user.pm25predictortest.MainActivity.onActivityResult(MainActivity.java:74) 
                         at android.app.Activity.dispatchActivityResult(Activity.java:6177) 
                         at android.app.ActivityThread.deliverResults(ActivityThread.java:3554) 
                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:3601)  
                         at android.app.ActivityThread.access$1300(ActivityThread.java:147)  
                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1333)  
                         at android.os.Handler.dispatchMessage(Handler.java:102)  
                         at android.os.Looper.loop(Looper.java:135)  
                         at android.app.ActivityThread.main(ActivityThread.java:5257)  
                         at java.lang.reflect.Method.invoke(Native Method)  
                         at java.lang.reflect.Method.invoke(Method.java:372)  
                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:921)  
                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:716) 

中的System.out.println()中的错误消息是在包含requestDataSet_al(MainService.class-> sendRequestToServer)的,所以我不认为这是捆绑的问题。 任何解决方案将不胜感激,谢谢!

+0

如果您执行MainActivity.this.startService(requestIntent);'相同的错误或不同? –

+0

同样的错误,但thx。 –

回答

0

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

由于每Documentation它是由系统每次都被叫客户明确通过调用startService(Intent)启动该服务,提供代表开始要求它提供的参数和一个唯一的整数令牌。

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

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

我使用IntentService的原因是把任务放到非UI线程中,但是如果我把我的命令放入onStartCommand()会使任务在UI线程中运行? –

+0

哈哈它不会影响UI线程。你可以使用后台线程中的startService。但我告诉你要覆盖IntentService中的onStartCommand。你见过我提供的文档链接吗? –

+0

它给了我一个NetworkOnMainThreadException。 –