android异步任务正确使用ui线程

发布于 2025-01-01 16:12:17 字数 4050 浏览 0 评论 0原文

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

有人告诉我,不同的方法可能会给 ui 线程带来压力,并且我需要让网络连接在后台或单独的线程上运行,以防止应用程序变慢。

我在 android 文档中阅读了有关 Async Task 的内容。

这是我的问题:

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

  2. 我该怎么做?

    public class GpsActivity 扩展 Activity {
    
    私人位置经理 lm;
    私有LocationListener位置监听器;
    公共静态 TelephonyManager tm;
    公共静态 TextView 电视;
    公共静态 Socket ;
    公共静态 PrintWriter 输出;
    
    
    /**
     * 首次创建活动时调用。
     */
    @覆盖
    公共无效onCreate(捆绑保存实例状态){
    super.onCreate(savedInstanceState);
    /**
     * 检索引用以提供对设备上电话服务信息的访问     
     */
    tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    setContentView(R.layout.main);
    /**
    * 检索引用以提供对系统定位服务的访问    
    */              
    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);    
    
    
     /**
      * 显式选择提供商,创建一组条件并让 android 选择可用的最佳提供商
      */
    
      标准条件 = new Criteria();
      criteria.setAccuracy(Criteria.ACCURACY_FINE);
      criteria.setAltitudeRequired(false);
      criteria.setBearingRequired(false);
      criteria.setCostAllowed(true);
      criteria.setPowerRequirement(Criteria.POWER_LOW);
      字符串提供者 = lm.getBestProvider(criteria, true);
      /**
       * 该方法有四个参数:
       提供商:您注册的提供商的名称
       minTime:通知的最小时间间隔,以毫秒为单位。
       minDistance:通知的最小距离间隔,以米为单位。
       侦听器:每次位置更新都会调用其 onLocationChanged() 方法的对象。
       */
       locationListener = new MyLocationListener();
       lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    
       电视 = (TextView) findViewById(R.id.textView1);
       tv.setText("我目前没有位置数据。");
    
       }
    
        /**
         * 将Android客户端连接到给定的服务器
         * 
         * @参数名称
         * 远程服务器的名称
         * @参数端口
         * 连接到远程服务器的端口号。
         * @抛出IOException
         * @抛出UnknownHostException
         */
        公共静态无效连接(字符串名称,int端口)
        抛出 UnknownHostException、IOException
    {
    
    s = new Socket(名称,端口);
    out = new PrintWriter(s.getOutputStream(), true);
    }
    
    /**
     * 向服务器发送字符串消息。
     * 
     * @参数消息
     * 要发送的消息。
     * @抛出IOException
     */
     public static void send(String msg) 抛出 IOException
     {
     if (!s.isClosed() && msg != null)
     {
        输出.println(消息);
        if (msg.contains("CMD_QUIT"))
        {
            关闭();
            s.close();
            Log.i("服务器连接", "客户端已断开连接。");
        }
    }
    }
    
     //用于当位置发生变化时接收来自LocationManager的通知
    
    私有类 MyLocationListener 实现 LocationListener{
    
    @覆盖
    公共无效onLocationChanged(位置loc){
        String txt = "纬度:" + loc.getLatitude() + "/n经度:" + loc.getLongitude();
        Log.i("地理位置", "我当前位置是:\n " + txt);
        tv.setText("我当前位置是:\n" + txt);
        最终字符串 msg = loc.getLongitude() + "\n" + loc.getLatitude() + "\n"
           + loc.getTime();
    
    
        //判断位置是否在指定区域(矩形)内
        双 lat0 = 14.618572;
        双长0 = 120.993816;
        双 lat1 = 14.619652;
        双长1 = 120.992770;
        双 lat2 = 14.620285;
        双长2 = 120.993451;
        双 lat3 = 14.619242;
        双长3 = 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 (rel1 >= 0 && rel2 >= 0 && rel3 >= 0 && rel4 >= 0 )
        {
    
            尝试
            {
            连接(“IP地址”,27960);
            发送(“CMD_HELLO”);
            发送(消息);
            tv.setText("位置在路网内...正在向服务器发送坐标");
            发送(“CMD_QUIT”);
            } catch (UnknownHostException e)
            {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            } catch (IOException e)
            {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
            }
    
    
        别的
        {
            tv.setText("当前位置在路网之外");
    
        }
        }
    
    
    
    
    
    @覆盖
    公共无效onProviderDisabled(字符串提供者){
        // TODO 自动生成的方法存根
    
    }
    
    @覆盖
    公共无效onProviderEnabled(字符串提供者){
        // TODO 自动生成的方法存根
    
    }
    
    @覆盖
    公共无效onStatusChanged(字符串提供者,int状态,捆绑额外){
        // TODO 自动生成的方法存根
    
    }
    
            }
            }
    

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喜爱纠缠 2025-01-08 16:12:17

仅供参考,您可以使用 runnOnUIThread(Runnable R) 来更改文本。

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

Just fyi you could use runnOnUIThread(Runnable R) to change the Text.

Anyway with AsyncTask is better because you don't freeze the UI while connecting.

病毒体 2025-01-08 16:12:17

能够做到这一点,并且按照教程操作即可。

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");

            }**


}


    }

}

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");

            }**


}


    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文