-2

我试图更新使用服务上的谷歌地图标记,但是当我使用“setParkingSpotMarker”功能,添加标记主线程列表中的每个项目都会收到错误“java.lang.IllegalStateException:Not on the main thread”错误的数据进行解析java.lang.IllegalStateException:不就当试图添加标记

函数“setParkingSpotMarker”在服务-DataUpdateService中的循环中调用。

我不知道如何改变我的代码,以便它会更新主thread.I标记看了一下,有些职位,但不知道如何去改变它在我的代码。

这是该服务:

package com.example.sailon; 
    import android.app.Service; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.os.Binder; 
    import android.os.IBinder; 
    import android.util.Log; 
    import java.util.ArrayList; 
    import java.util.Timer; 
    import java.util.TimerTask; 

import com.google.android.gms.maps.model.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 

public class DataUpdateService extends Service { 
    Timer myTimer = new Timer(); 
    MyTimerTask myTask = new MyTimerTask(); 
    MyMap mymap; 
    String teamID; 
    static LatLng teamLocation; 
    ArrayList<TeamsList> teamsList= new ArrayList<TeamsList>() ; 
    public ArrayList<UnitInHeatForMap> unitswithteam= new ArrayList<UnitInHeatForMap>(); 
    String action; 
    Context fromContext; 
    String CompName; 
    String heatNum; 
    boolean isSailor; 
    String usermail; 
    GPSTracker gps; 


    private final IBinder mBinder = new LocalBinder(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.d("PS", "DataUpdateService onStartCommand"); 
     return Service.START_NOT_STICKY; 
    } 

    @Override 
    // return thee instance of the local binder to the activity 
    public IBinder onBind(Intent intent) { 
     Log.d("PS", "DataUpdateService onBind"); 
     return mBinder; 
    } 

    public class LocalBinder extends Binder { 
     DataUpdateService getService() { 
      Log.d("PS", "DataUpdateService LocalBinder onBind"); 
      return DataUpdateService.this; 
     } 
    } 

    public class MyTimerTask extends TimerTask { 
     @Override 
     public void run() { 
      String unitToUpdate= mymap.getUnitToUpdate (CompName,heatNum,usermail); 
      Log.d("NY","CompName " +CompName); 
      Log.d("NY","heatNum " +heatNum); 
      Log.d("NY","usermail " +usermail); 

      Log.d("NY","unitToUpdate" +unitToUpdate); 

      Log.d("NY","isSailor" +isSailor); 
      if (isSailor){ 
       gps = new GPSTracker(DataUpdateService.this,unitToUpdate); 
       if(! (gps.canGetLocation())){  
        gps.showSettingsAlert(); 
       } 
      } 

      unitswithteam=mymap.refresh (CompName,heatNum); 

      int j= unitswithteam.size(); 
      for (int i=0; i<j;i++){ 
       teamID=unitswithteam.get(i).getTeamID(); 
       Log.d("NY","teamID "+i+teamID); 
       UnitsInHeats us=unitswithteam.get(i).getUnit(); 
       teamLocation = new LatLng(us.getLat(),us.getLng()); 
       Log.d("NY","team location "+i + " "+us.getLat()); 
       mymap.setParkingSpotMarker(teamLocation,teamID); 

       if (i==(j-1)){ 
        CameraPosition secound =new CameraPosition.Builder() 
        .target(teamLocation) 
        .zoom(15.5f) 
        .bearing(300) 
        .tilt(50) 
        .build(); 
        mymap.moveMyMapCamera(secound); 
       } 
     } 

     } 
    } 

    // called from the activity 
    public void MapUpdateFromService(Context context, MyMap map, final String action, 
           String CompName, String heatNum, boolean isSailor , String usermail) { 
     Log.d("PS", "DataUpdateService MapUpdateFromService"); 
     this.mymap = map; 
     this.action = action; 
     this.CompName=CompName; 
     this.heatNum=heatNum; 
     this.isSailor=isSailor; 
     this.usermail=usermail; 

     // this command activate the run function from the inner class MyTimerTask every 5 seconds. 
     myTimer.schedule(myTask,0,5000); 
    } 


    public void onDestroy() { 
     super.onDestroy(); 
     // cancel the scheduler. 
     myTimer.cancel(); 
    } 
} 

这是调用该服务的活动:

package com.example.sailon; 
import java.util.ArrayList; 
import com.google.android.gms.maps.MapFragment; 
import com.google.android.gms.maps.model.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import android.app.ActionBar; 
import android.app.Activity; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 

public class Map extends Activity { 
    Bundle extras; 
// private GoogleMap map; 
    static LatLng teamLocation; 
    //public static ArrayList<Teams> teams; 
    ArrayList<TeamsList> teamsList= new ArrayList<TeamsList>() ; 
    Marker mark; 
    double lat; 
    double lng; 
    GPSTracker gps; 
    String Location ; 
    String teamID; 
    String CompName; 
    MyMap mymap; 
    String heatNum; 
    String CompID; 
    boolean isSailor; 
    String usermail; 
    static LatLng BeerSheva = new LatLng(31.250919, 34.783916); 
    public ArrayList<UnitInHeatForMap> unitswithteam= new ArrayList<UnitInHeatForMap>(); 
// ArrayList<LatLng> List= new ArrayList<LatLng>() ; 
    DataUpdateService dbuService; 
    boolean dbuBound=false;// when service connected get true 

    @Override 
protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_map); 
     mymap= new MyMap(this,((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap()); 
     //map=((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap(); 

     extras = getIntent().getExtras(); 
     CompName=extras.getString("CompName"); 
     heatNum=extras.getString("heatNum"); 
     isSailor=extras.getBoolean("isSailor"); 
     usermail=extras.getString("usermail"); 
     Log.d("CompName",CompName); 
     Log.d("heatNum",heatNum); 
     // get action bar 
     ActionBar actionBar = getActionBar(); 
     // Enabling Up/Back navigation 
     actionBar.setDisplayHomeAsUpEnabled(true); 


     if (mymap!=null){ 
      Log.d("PS", "map isnt null"); 
      mymap.setMapType(); 
      mymap.setMyLocationEnabled(true); 
      CameraPosition firstZom =new CameraPosition.Builder() 
      .target(BeerSheva) 
      .zoom(15.5f) 
      .bearing(300) 
      .tilt(50) 
      .build(); 

      mymap.moveMyMapCamera(firstZom); 
     } 



    } 



     // serviceConnerction is an interface that must be implemented when using bound service 
     private ServiceConnection sConnection=new ServiceConnection() { 
      @Override 
      public void onServiceConnected(ComponentName name, IBinder service) { 
       Log.d("PS", "Map onServiceConnected"); 
       DataUpdateService.LocalBinder binder=(DataUpdateService.LocalBinder)service; 
       dbuService=binder.getService(); 
       Log.d("PS", "Map callupdate"); 
       dbuService.MapUpdateFromService(Map.this,mymap,"ActionSearch",CompName,heatNum, isSailor,usermail); 
       dbuBound=true; 
      } 

      @Override 
      public void onServiceDisconnected(ComponentName name) { 
       Log.d("PS", "Map onServiceDisconnected"); 
       dbuBound=false; 
      } 
     }; 

     @Override 
     protected void onStart() { 
      super.onStart(); 
      // Bind to DataUpdateService 
      Log.d("PS", "Map onStart"); 
      Intent intent= new Intent(this,DataUpdateService.class); 
      bindService(intent,sConnection, Context.BIND_AUTO_CREATE); 
     } 

     @Override 
     protected void onStop() { 
      super.onStop(); 
      // Unbind from the service 
      Log.d("PS", "Map onStop"); 
      if(dbuBound){ 
       unbindService(sConnection); 
       dbuBound=false; 
      } 
     } 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.activity_main_actions, menu); 

     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Take appropriate action for each action item click 
     switch (item.getItemId()) { 
     case R.id.logoutAction:  
      Intent i = new Intent(Map.this, MainActivity.class); 
      startActivity(i); 
      return true; 
     case R.id.VideoAction:  
      Intent intent = new Intent("android.media.action.VIDEO_CAMERA"); 
      startActivity(intent); 
      return true; 
     case R.id.CallAction:  
      Intent call = new Intent(Intent.ACTION_DIAL); 
      startActivity(call); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 
    } 


} 

这是地图的CALSS: 包com.example.sailon;

import android.content.Context; 

import android.util.Log; 


import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 

import com.google.android.gms.maps.model.BitmapDescriptorFactory; 
import com.google.android.gms.maps.model.CameraPosition; 
import com.google.android.gms.maps.model.LatLng; 

import com.google.android.gms.maps.model.MarkerOptions; 
import com.parse.ParseException; 

import java.util.ArrayList; 


/** 
* Created by Evyatar.m on 21/02/2015. 
*/ 
public class MyMap { 

    private GoogleMap map; 
    static LatLng BeerSheva = new LatLng(31.250919, 34.783916); 
    String CompID; 
    String teamID; 
    String CompName; 
    String heatNum; 
    ArrayList<TeamsList> teamsList= new ArrayList<TeamsList>() ; 
    public ArrayList<UnitInHeatForMap> unitswithteam2= new ArrayList<UnitInHeatForMap>(); 
    static LatLng teamLocation; 
    Model DB; 


    public MyMap(Context context, GoogleMap map) { 
     Log.d("PS", "MyMap builder"); 
     DB = Model.getInstance(context); 
     this.map = map; 

    } 

    public String getUnitToUpdate (String CompName,String heatNum, String usermail){ 
     String unit=null; 
     try { 
      CompID= DB.getCompIDByName(CompName);  
     } catch (com.parse.ParseException e) {  
      e.printStackTrace(); 
     } 
     try { 
      unit= DB.getUnitToUpdateFromDB (CompID,heatNum, usermail); 
     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return unit; 
    } 
    public void setMyLocationEnabled(boolean b){ 
     Log.d("PS", "MyMap set location enable"); 
     map.setMyLocationEnabled(true); 
    } 


    public void setParkingSpotMarker(LatLng teamLocation,String teamID) { 
     Log.d("PS", "ParkingMap setParkinSpotMarker"); 
     map.addMarker(new MarkerOptions() 
       .position(teamLocation) 
       .icon(BitmapDescriptorFactory.fromResource(R.drawable.iconsmall)) 
       .title("Team " +teamID)).showInfoWindow(); 


    } 

    public void setMapType(){ 
     Log.d("PS", "MyMap setType"); 
    map.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
    } 

    public void moveMyMapCamera(CameraPosition firstZom) { 
     Log.d("PS", "MyMap moveParkingMapCamera"); 
     map.moveCamera(CameraUpdateFactory.newCameraPosition(firstZom)); 
    } 
    //updates all points on map 

    public ArrayList<UnitInHeatForMap> refresh (String CompName,String heatNum){ 
     Log.d("PS", "MyMap refresh"); 
     try { 
      CompID= DB.getCompIDByName(CompName);  
     } catch (com.parse.ParseException e) {  
      e.printStackTrace(); 
     } 

     try { 
      DB.setUnitInHeatForMap (new Model.CallbackModel() { 
       @Override 
       public void done (ArrayList<UnitInHeatForMap> unitswithteam){ 
        if (unitswithteam.size() >0){ 
         unitswithteam2=unitswithteam; 
        } 

       } 
      }, CompID, heatNum,this); 

     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


     return unitswithteam2; 



} 


} 

请帮我 感谢!**

回答

0

在后台线程上运行TimerTaskrun方法,你只能更新主线程在地图上。

所以,你必须在以下地图UI更新代码包装成runOnUiThread(

 mymap.setParkingSpotMarker(teamLocation,teamID); 

     if (i==(j-1)){ 
      CameraPosition secound =new CameraPosition.Builder() 
      .target(teamLocation) 
      .zoom(15.5f) 
      .bearing(300) 
      .tilt(50) 
      .build(); 
      mymap.moveMyMapCamera(secound); 
     } 

你需要有一个Activity申请runOnUIThread,所以你需要把你的

fromContext = ((Map)context);

在您的MapUpdateFromService方法的第一行内。然后,您可以拨打的run()方法拨打runOnUiThread()

((Map)fromContext).runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     //run your Map UI update code 
    } 
}); 

这也是一个类似的问题this problem

+0

它的作品谢谢! – 2015-03-20 07:57:52

相关问题