android Async Task正确使用ui线程

时间:2012-02-01 10:30:58

标签: android android-asynctask

下面是我准备好的代码,用于侦听位置更新,一旦位置在指定区域内,它将连接到服务器并开始发送它的位置和时间戳,直到它退出该区域。

我被告知不同的方法可能会强调ui线程,并且我需要让网络连接在后台运行或在单独的线程上运行以防止应用程序变慢。

我正在阅读android文档中的Async Task

以下是我的问题:

  1. 我想我需要在应用程序确定它位于指定区域(矩形)内以及它尝试连接并发送到服务器的那一刻后,将该部分放入一个单独的线程中?

  2. 我将如何做到这一点?

    public class GpsActivity extends Activity {
    
    private LocationManager lm;
    private LocationListener locationListener;
    public static TelephonyManager tm;
    public static TextView tv;
    public static Socket s;
    public static PrintWriter out;
    
    
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /**
     * retrieve a reference to provide access to information about the telephony services on the device     
     */
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    setContentView(R.layout.main);
    /**
    * retrieve a reference to provide access to the system location services    
    */              
    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);    
    
    
     /**
      * explicitly select the provider, create a set of Criteria and let android choose the best provider available
      */
    
      Criteria criteria = new Criteria();
      criteria.setAccuracy(Criteria.ACCURACY_FINE);
      criteria.setAltitudeRequired(false);
      criteria.setBearingRequired(false);
      criteria.setCostAllowed(true);
      criteria.setPowerRequirement(Criteria.POWER_LOW);
      String provider = lm.getBestProvider(criteria, true);
      /**
       * This method takes in four parameters:
       provider: The name of the provider with which you register
       minTime: The minimum time interval for notifications, in milliseconds.
       minDistance: The minimum distance interval for notifications, in meters.
       listener: An object whose onLocationChanged() method will be called for each location update.
       */
       locationListener = new MyLocationListener();
       lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    
       tv = (TextView) findViewById(R.id.textView1);
       tv.setText("I currently have no Location Data.");
    
       }
    
        /**
         * Connects the Android Client to a given server
         * 
         * @param name
         *            The name of the remote server
         * @param port
         *            Port number to connect to at the remote server.
         * @throws IOException
         * @throws UnknownHostException
         */
        public static void connect(String name, int port)
        throws UnknownHostException, IOException
    {
    
    s = new Socket(name, port);
    out = new PrintWriter(s.getOutputStream(), true);
    }
    
    /**
     * Sends a string message to the server.
     * 
     * @param msg
     *            The message to be sent.
     * @throws IOException
     */
     public static void send(String msg) throws IOException
     {
     if (!s.isClosed() && msg != null)
     {
        out.println(msg);
        if (msg.contains("CMD_QUIT"))
        {
            out.close();
            s.close();
            Log.i("ServerConnection", "Client Disconnected.");
        }
    }
    }
    
     //Used for receiving notifications from the LocationManager when the location has changed
    
    private class MyLocationListener implements LocationListener{
    
    @Override
    public void onLocationChanged(Location loc) {
        String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude();
        Log.i("GeoLocation", "My current location is:\n " + txt);
        tv.setText("My current location is:\n" + txt);
        final String msg = loc.getLongitude() + "\n" + loc.getLatitude() + "\n"
           + loc.getTime();
    
    
        //determines if the location is within a designated area (rectangle)
        double lat0 = 14.618572;
        double long0 = 120.993816;
        double lat1 = 14.619652;
        double long1 = 120.992770;
        double lat2 = 14.620285;
        double long2 = 120.993451;
        double lat3 = 14.619242;
        double long3 = 120.994497;
        double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0));
        double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1));
        double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2));
        double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3));
    
        // if yes, it will connect to server and send the location and timestamp
    
    
        if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0 )
        {
    
            try
            {
            connect("IP address", 27960);
            send("CMD_HELLO");
            send(msg);
            tv.setText("Location is inside the road network...sending coordinates to server");
            send("CMD_QUIT");
            } catch (UnknownHostException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            }
    
    
        else
        {
            tv.setText("Current location is outside the road network");
    
        }
        }
    
    
    
    
    
    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    
    }
    
            }
            }
    

2 个答案:

答案 0 :(得分:0)

是否能够按照tutorial进行操作。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 /**
  * retrieve a reference to provide access to information about the telephony services on the device     
  */
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    setContentView(R.layout.main);
 /**
  * retrieve a reference to provide access to the system location services    
  */              
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);    


/**
explicitly select the GPS provider, create a set of Criteria and let android choose 
the best provider available
 */

Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = lm.getBestProvider(criteria, true);
/**
 * This method takes in four parameters:
provider: The name of the provider with which you register
minTime: The minimum time interval for notifications, in milliseconds.
minDistance: The minimum distance interval for notifications, in meters.
listener: An object whose onLocationChanged() method will be called for each location update.
 */
locationListener = new MyLocationListener();
lm.requestLocationUpdates(provider, 1000, 1, locationListener);

tv = (TextView) findViewById(R.id.textView1);
tv.setText("I currently have no Location Data.");

}

/**
 * Connects the Android Client to a given server
 * 
 * @param name
 *            The name of the remote server
 * @param port
 *            Port number to connect to at the remote server.
 * @throws IOException
 * @throws UnknownHostException
 */
 public static void connect(String name, int port)
        throws UnknownHostException, IOException
{

    s = new Socket(name, port);
    out = new PrintWriter(s.getOutputStream(), true);
}

/**
 * Sends a string message to the server.
 * 
 * @param msg
 *            The message to be sent.
 * @throws IOException
 */
 public static void send(String outmsg) throws IOException
{
    if (!s.isClosed() && outmsg != null)
    {
        out.println(outmsg);
        out.close();
        s.close();
        }}



  //Used for receiving notifications from the LocationManager when the location has changed

private class MyLocationListener implements LocationListener{


    @Override
    public void onLocationChanged(Location loc) {
        String txt = "Latitude:" + loc.getLatitude() + "/nLongitude:" + loc.getLongitude();
        Log.i("GeoLocation", "My current location is:\n " + txt);
        tv.setText("My current location is:\n" + txt);
        String msg=loc.getLongitude() + "\n" + loc.getLatitude() + "\n"
        + loc.getTime();
        tv1 = (TextView) findViewById(R.id.textView2);
        tv2 = (TextView) findViewById(R.id.textView3);  
        //determines if the location is within a designated area (rectangle)
        double lat0 = 14.609794;
        double long0 = 120.986018;
        double lat1 = 14.608966;
        double long1 = 120.986037;
        double lat2 = 14.609031;
        double long2 = 120.984991;
        double lat3 = 14.609877;
        double long3 = 120.985069;
        double rel1 = (loc.getLongitude()- long0)*(lat1 - lat0)- ((loc.getLatitude()-lat0)*(long1-long0));
        double rel2 = (loc.getLongitude()- long1)*(lat2 - lat1)- ((loc.getLatitude()-lat1)*(long2-long1));
        double rel3 = (loc.getLongitude()- long2)*(lat3 - lat2)- ((loc.getLatitude()-lat2)*(long3-long2));
        double rel4 = (loc.getLongitude()- long3)*(lat0 - lat3)- ((loc.getLatitude()-lat3)*(long0-long3));

        // if yes, it will connect to server and send the location and timestamp

       if (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0 )
        {
           tv1.setText("Location is inside the road network...");
           **new connectSend().execute(msg);**  
           }


        else
        {
            tv1.setText("Current location is outside the road network");

        }
        }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    **public class connectSend extends AsyncTask<String, String, String>{

        @Override
        protected String doInBackground(String... msg) {
            // TODO Auto-generated method stub
            String result;

            try
            {
            connect("ip address", port);

            send(msg[0]);

            result = "SUCCESSFUL coordinates sent to server";

            } catch (UnknownHostException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
                result = "NOT SUCCESSFUL ";
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
                result = "NOT SUCCESSFUL ";
            }
            return result;}

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            tv2.setText("result");

            }**


}


    }

}

答案 1 :(得分:0)

你可以使用runnOnUIThread(Runnable R)更改文本。

无论如何使用AsyncTask更好,因为你在连接时不会冻结UI。