ServerManager类的问题

时间:2011-05-09 12:01:31

标签: android multithreading

我有一个应用客户端 - 服务器的东西......除了真正的跟踪设备之外别无他法。 我的意思是客户端在Android手机上,它向服务器发送GPS数据....将数据传送到服务器我想将其发送到另一个活动....

数据在工作线程中接收,并发送到主要活动。

为此,我使用了一个ServerManager类,其中工作线程存储了最后收到的GPS数据。

这是工作线程:

Scanner is = new Scanner(new DataInputStream(
                this.clientSocket.getInputStream()));

        while (!stop) {
            while (is.hasNext()) {
                try {
                    longitude = is.next();
                                            latitude = is.next();
                                          // save last data
                    ServerManager.getInstance().setLastLatitude(latitude);
                    ServerManager.getInstance().setLastLongitude(longitude);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

这是我的ServerManager类:

公共类ServerManager {

String lastLatitude;
String lastLongitude;

// singleton
private static ServerManager instance = null;

private ServerManager() {

}

public static ServerManager getInstance() {
    if (instance == null)
        instance = new ServerManager();
    return instance;
}

public String getLastLatitude() {
    return lastLatitude;
}

public void setLastLatitude(String lastLatitude) {
    this.lastLatitude = lastLatitude;
}

public String getLastLongitude() {
    return lastLongitude;
}

public void setLastLongitude(String lastLongitude) {
    this.lastLongitude = lastLongitude;
}

}


最后,这是从ServerManager类请求这些点的活动:

public void onCreate(Bundle savedInstanceState){

    super.onCreate(savedInstanceState);
    setContentView(R.layout.server4);    

    mapView = (MapView) findViewById(R.id.mapview1);
    mapView.setBuiltInZoomControls(true);
    mc = mapView.getController();


   longitude=Integer.parseInt(ServerManager.getInstance().getLastLongitude());
   latitude=Integer.parseInt(ServerManager.getInstance().getLastLatitude());

  p=new GeoPoint(longitude,latitude);

   theRouteDraw(p);//here I draw those points on the map

   }

问题:

为什么当我尝试调用最后一个活动时,我得到了这个错误:

05-08 23:45:40.409: ERROR/AndroidRuntime(360): Uncaught handler: thread main exiting due to uncaught exception

05-08 23:45:40.459: ERROR/AndroidRuntime(360): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.server/com.server.Server4}: java.lang.NumberFormatException: unable to parse 'null' as integer

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.os.Handler.dispatchMessage(Handler.java:99)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.os.Looper.loop(Looper.java:123)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at 

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at java.lang.reflect.Method.invokeNative(Native Method)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at java.lang.reflect.Method.invoke(Method.java:521)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at dalvik.system.NativeStart.main(Native Method)
05-08 23:45:40.459: ERROR/AndroidRuntime(360): Caused by: java.lang.NumberFormatException: unable to parse 'null' as integer

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at java.lang.Integer.parseInt(Integer.java:347)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at java.lang.Integer.parseInt(Integer.java:323)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at com.server.Server4.onCreate(Server4.java:47)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)

05-08 23:45:40.459: ERROR/AndroidRuntime(360):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)

更新:

我的应用程序是一种GPS跟踪器。它有一个部分可以进行实时跟踪。这意味着什么?..............这意味着它移动的客户端...在一条路线上,描述他沿路线移动的所有GPS数据都被发送到服务器。

每次更改位置时,新数据都会发送到服务器部分。

服务器在工作线程中接收这些点.....然后我将它们传递给ServerManager类。

现在,当我打电话给那个活动(我最初的问题中的最后一个代码)时,我希望它从ServerManager询问他拥有的最后一个数据.....我希望它只要客户端就可以询问它移动....

U说我应该使用处理程序将数据从woker发送到活动....但我想要其他....-只要工作人员收到新的更新,活动就像数据一样。

你现在明白了吗????

UPDATE2:

protected GeoPoint doInBackground(Void...voids){


        try{

   longitude=Integer.parseInt(ServerManager.getInstance().getLastLongitude());
   latitude=Integer.parseInt(ServerManager.getInstance().getLastLatitude());

   p=new GeoPoint(longitude,latitude);
   publishProgress(p);

        }

        catch(Exception e)

        {
            e.printStackTrace();
        }
        return p;
    }

这是我的doInBackground方法....我没有错误,但我想知道我应该在它内部使用什么循环,以便只要我在那个活动中就要求数据...并停止我离开活动后立即询问数据????

那么....使用什么循环?


最后,感谢@ MByD

public class Server4 extends MapActivity {

    private LocationManager lm;

    private LocationListener locationListener;

    private MyLocationOverlay myLocOverlay;


    private MapView mapView;

    private MapController mc;

    GeoPoint p;

    InitTask init_task;

    int latitude;
    int longitude;
    DBAdapter db;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.server4);

        mapView = (MapView) findViewById(R.id.mapview1);
        mapView.setBuiltInZoomControls(true);
        mc = mapView.getController();
    }

    public void onResume() {

         super.onResume();
         init_task = new InitTask();
        init_task.execute();
    }

    public class InitTask extends AsyncTask<Void, GeoPoint, Void> {

        GeoPoint p;

        protected Void doInBackground(Void... voids) {

            try {

                while (true) {
                    longitude = Integer.parseInt(ServerManager.getInstance()
                            .getLastLongitude());
                    latitude = Integer.parseInt(ServerManager.getInstance()
                            .getLastLatitude());

                    p = new GeoPoint(longitude, latitude);
                    publishProgress(p);
                    Thread.sleep(500);
                }

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

        protected void onProgressUpdate(GeoPoint... progress1) {

            theRouteDraw(progress1[0]);
            //initMyLocation();

        }

    }

    public void onPause(){

        init_task.cancel(true);
        super.onPause();

    }

    public void theRouteDraw(GeoPoint p1) {
        mc.animateTo(p1);
        mc.setZoom(13);
        mapView.invalidate();
        mapView.setSatellite(true);

    }

    /*private void initMyLocation() {
        myLocOverlay = new MyLocationOverlay(this, mapView);
        myLocOverlay.enableMyLocation();
        mapView.getOverlays().add(myLocOverlay);

    }*/

    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

}

1 个答案:

答案 0 :(得分:1)

您正尝试在此处解析null:longitude=Integer.parseInt(ServerManager.getInstance().getLastLongitude());

因为您从getLastLongitude()

收到空

似乎工作线程还没有调用setLastLatitude ......

编辑:

  1. doInBackground()内使用循环,并在循环结束处添加sleep(X),其中X是检查之间的间隔。

  2. 使用cancel方法在帖子上调用onPause()(并将创建移至onResume())。

  3. 示例:

       try{
           while(keepGoing) // some boolean that is set to true
           {
               longitude=Integer.parseInt(ServerManager.getInstance().getLastLongitude());
               latitude=Integer.parseInt(ServerManager.getInstance().getLastLatitude());
    
               p=new GeoPoint(longitude,latitude);
               publishProgress(p);
               Thread.sleep(interval); // interval specifies the time to wait in ms.
           }
       }
       ...