Android的异步任务UI线程的正确用法 [英] android Async Task for proper usage of ui thread

查看:189
本文介绍了Android的异步任务UI线程的正确用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的prepared code来监听位置更新,一旦该位置是一个指定区域内,它会连接到服务器,并开始发送它的位置和时间标记,直到它离开该地区。

我被告知,不同的方法强调了UI线程,而我需要有网络连接在后台或在一个单独的线程prevent运行中的应用程序变慢。

我正在阅读有关异步任务 android的文档中获得。

下面是我的问题:


  1. 我想我需要放在一个单独的线程中的部分应用程序决定了它是指定的区域(矩形),它尝试连接并发送到服务器的那一刻后里面?


  2. 我会怎么做呢?

     公共类GpsActivity延伸活动{私人的LocationManager流明;
    私人LocationListener的LocationListener的;
    公共静态TelephonyManager TM;
    公共静态TextView的电视;
    公共静态插座S;
    公共静态的PrintWriter出来;
    / **
     *当第一次创建活动调用。
     * /
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    / **
     *检索的参考,以提供关于设备上的电话服务的访问到的信息
     * /
    TM =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    的setContentView(R.layout.main);
    / **
    *检索的参考,以提供对系统的访问位置信息服务
    * /
    LM =(的LocationManager)getSystemService(Context.LOCATION_SERVICE);
     / **
      *明确选择供应商,建立一套标准,让机器人可以选择最佳供应商
      * /  标准标准=新标准();
      criteria.setAccuracy(Criteria.ACCURACY_FINE);
      criteria.setAltitudeRequired(假);
      criteria.setBearingRequired(假);
      criteria.setCostAllowed(真);
      criteria.setPowerRequirement(Criteria.POWER_LOW);
      字符串提供商= lm.getBestProvider(标准,真正的);
      / **
       *这种方法需要在四个参数:
       供应商:与您注册商的名称
       minTime:对于通知的最小时间间隔,单位为毫秒。
       minDistance依旧:对于通知的最小距离间隔,单位为米。
       监听器:一个对象,其onLocationChanged()方法将被调用为每个位置更新。
       * /
       LocationListener的=新MyLocationListener();
       lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,LocationListener的);   电视=(的TextView)findViewById(R.id.textView1);
       tv.setText(我目前还没有位置数据。);   }    / **
         *将Android客户端,以给定的服务器
         *
         * @参数名称
         *远程服务器的名称
         * @参数端口
         *端口号码在远程服务器连接到。
         *引发IOException
         * @throws的UnknownHostException
         * /
        公共静态无效连接(字符串名称,诠释端口)
        抛出的UnknownHostException,IOException异常
    {S =新的Socket(名称,端口);
    OUT =的新PrintWriter(s.getOutputStream(),TRUE);
    }/ **
     *将字符串发送信息到服务器。
     *
     * @参数味精
     *要发送的消息。
     *引发IOException
     * /
     公共静态无效的send(弦乐味精)抛出IOException异常
     {
     如果(s.isClosed()及!&安培;味精!= NULL)
     {
        通过out.println(MSG);
        如果(msg.contains(CMD_QUIT))
        {
            out.close();
            S.CLOSE();
            Log.i(ServerConnection,客户端断开连接。);
        }
    }
    } //用于从的LocationManager接收通知时的位置发生了变化私有类MyLocationListener实现LocationListener的{@覆盖
    公共无效onLocationChanged(位置LOC){
        字符串的txt =纬度:+ loc.getLatitude()+/ nLongitude:+ loc.getLongitude();
        Log.i(地理定位,我的当前位置为:\\ n+ TXT);
        tv.setText(我的当前位置为:\\ n+ TXT);
        最后弦乐味精= loc.getLongitude()+\\ n+ loc.getLatitude()+\\ n
           + loc.getTime();
        //确定该位置是一个指定区域内(矩形)
        双lat0 = 14.618572;
        双long0 = 120.993816;
        双LAT1 = 14.619652;
        双long1 = 120.992770;
        双LAT2 = 14.620285;
        双long2 = 120.993451;
        双lat3 = 14.619242;
        双long3 = 120.994497;
        双REL1 =(loc.getLongitude() - long0)*(LAT1 - lat0) - ((loc.getLatitude() - lat0)*(long1-long0));
        双REL2 =(loc.getLongitude() - long1)*(LAT2 - LAT1) - ((loc.getLatitude() - LAT1)*(long2-long1));
        双REL3 =(loc.getLongitude() - long2)*(lat3 - LAT2) - ((loc.getLatitude() - LAT2)*(long3-long2));
        双rel4 =(loc.getLongitude() - long3)*(lat0 - lat3) - ((loc.getLatitude() - lat3)*(long0-long3));    //如果是,它会连接到服务器并发送位置和时间戳
        如果(REL1> = 0&放大器;&放大器; REL2> = 0&放大器;&放大器; REL3> = 0&放大器;&放大器; rel4> = 0)
        {        尝试
            {
            连接(IP地址,27960);
            送(CMD_HELLO);
            发送(MSG);
            tv.setText(地点的道路网络中发送...坐标到服务器);
            送(CMD_QUIT);
            }赶上(的UnknownHostException E)
            {
                // TODO自动生成catch块
                e.printStackTrace();
            }赶上(IOException异常E)
            {
                // TODO自动生成catch块
                e.printStackTrace();
            }
            }
        其他
        {
            tv.setText(当前位置为道路网外);    }
        }@覆盖
    公共无效onProviderDisabled(字符串提供商){
        // TODO自动生成方法存根}@覆盖
    公共无效onProviderEnabled(字符串提供商){
        // TODO自动生成方法存根}@覆盖
    公共无效onStatusChanged(字符串提供商,INT地位,捆绑演员){
        // TODO自动生成方法存根}        }
            }



解决方案

之所以能够做到这一点,它的工作通过执行<一个href=\"http://mrkn.co/s/video_tutorial_android_application_development_asynctask_$p$pferences_and_options_menu,257/index.html\"相对=nofollow>教程。

 公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
 / **
  *检索的参考,以提供关于设备上的电话服务的访问到的信息
  * /
    TM =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    的setContentView(R.layout.main);
 / **
  *检索的参考,以提供对系统的访问位置信息服务
  * /
LM =(的LocationManager)getSystemService(Context.LOCATION_SERVICE);
/ **
明确选择GPS提供商,创建一套标准,让Android的选择
可用的最佳供应商
 * /标准标准=新标准();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(假);
criteria.setBearingRequired(假);
criteria.setCostAllowed(真);
criteria.setPowerRequirement(Criteria.POWER_LOW);
字符串提供商= lm.getBestProvider(标准,真正的);
/ **
 *这种方法需要在四个参数:
供应商:与您注册商的名称
minTime:对于通知的最小时间间隔,单位为毫秒。
minDistance依旧:对于通知的最小距离间隔,单位为米。
监听器:一个对象,其onLocationChanged()方法将被调用为每个位置更新。
 * /
LocationListener的=新MyLocationListener();
lm.requestLocationUpdates(供应商,1000,1,LocationListener的);电视=(的TextView)findViewById(R.id.textView1);
tv.setText(我目前还没有位置数据。);}/ **
 *将Android客户端,以给定的服务器
 *
 * @参数名称
 *远程服务器的名称
 * @参数端口
 *端口号码在远程服务器连接到。
 *引发IOException
 * @throws的UnknownHostException
 * /
 公共静态无效连接(字符串名称,诠释端口)
        抛出的UnknownHostException,IOException异常
{    S =新的Socket(名称,端口);
    OUT =的新PrintWriter(s.getOutputStream(),TRUE);
}/ **
 *将字符串发送信息到服务器。
 *
 * @参数味精
 *要发送的消息。
 *引发IOException
 * /
 公共静态无效发送(字符串outmsg)抛出IOException异常
{
    如果(s.isClosed()及!&安培; outmsg!= NULL)
    {
        通过out.println(outmsg);
        out.close();
        S.CLOSE();
        }}  //用于从的LocationManager接收通知时的位置发生了变化私有类MyLocationListener实现LocationListener的{
    @覆盖
    公共无效onLocationChanged(位置LOC){
        字符串的txt =纬度:+ loc.getLatitude()+/ nLongitude:+ loc.getLongitude();
        Log.i(地理定位,我的当前位置为:\\ n+ TXT);
        tv.setText(我的当前位置为:\\ n+ TXT);
        弦乐味精= loc.getLongitude()+\\ n+ loc.getLatitude()+\\ n
        + loc.getTime();
        TV1 =(的TextView)findViewById(R.id.textView2);
        TV2 =(的TextView)findViewById(R.id.textView3);
        //确定该位置是一个指定区域内(矩形)
        双lat0 = 14.609794;
        双long0 = 120.986018;
        双LAT1 = 14.608966;
        双long1 = 120.986037;
        双LAT2 = 14.609031;
        双long2 = 120.984991;
        双lat3 = 14.609877;
        双long3 = 120.985069;
        双REL1 =(loc.getLongitude() - long0)*(LAT1 - lat0) - ((loc.getLatitude() - lat0)*(long1-long0));
        双REL2 =(loc.getLongitude() - long1)*(LAT2 - LAT1) - ((loc.getLatitude() - LAT1)*(long2-long1));
        双REL3 =(loc.getLongitude() - long2)*(lat3 - LAT2) - ((loc.getLatitude() - LAT2)*(long3-long2));
        双rel4 =(loc.getLongitude() - long3)*(lat0 - lat3) - ((loc.getLatitude() - lat3)*(long0-long3));        //如果是,它会连接到服务器并发送位置和时间戳       如果(REL1&GT; = 0&放大器;&放大器; REL2&GT; = 0&放大器;&放大器; REL3&GT; = 0&放大器;&放大器; rel4&GT; = 0)
        {
           tv1.setText(位置是路网内......);
           **新connectSend()执行(MSG)。**
           }
        其他
        {
            tv1.setText(当前位置为道路网外);        }
        }    @覆盖
    公共无效onProviderDisabled(字符串提供商){
        // TODO自动生成方法存根    }    @覆盖
    公共无效onProviderEnabled(字符串提供商){
        // TODO自动生成方法存根    }    @覆盖
    公共无效onStatusChanged(字符串提供商,INT地位,捆绑演员){
        // TODO自动生成方法存根    }    **公共类connectSend扩展的AsyncTask&LT;字符串,字符串,字符串&GT; {        @覆盖
        保护字符串doInBackground(字符串...味精){
            // TODO自动生成方法存根
            字符串结果;            尝试
            {
            连接(IP地址,口);            发送(MSG [0]);            结果=成功的坐标发送到服务器;            }赶上(的UnknownHostException E)
            {
                // TODO自动生成catch块
                e.printStackTrace();
                结果=未成功;
            }赶上(IOException异常E)
            {
                // TODO自动生成catch块
                e.printStackTrace();
                结果=未成功;
            }
            返回结果;}        @覆盖
        保护无效onPostExecute(字符串结果){
            // TODO自动生成方法存根
            super.onPostExecute(结果);
            tv2.setText(结果);            } **
}
    }}

Below is my prepared code which listens for location updates and once the location is within a designated area, it will connect to a server and will start sending it's locations and time stamps until it exit the area.

I was advised that the different methods may stress out the ui thread and that i need to have the network connection to run in the background or on a separate thread to prevent slow down in the application.

I was reading about Async Task in the android documentation.

Here are my questions:

  1. I guess i need to put in a separate thread the part after the app determines that it is inside the designated area (rectangle) and the moment that it is trying to connect and send to the server?

  2. How will i do that ?

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

解决方案

Was able to do it and it worked by following the 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");

            }**


}


    }

}

这篇关于Android的异步任务UI线程的正确用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆