【问题标题】:Adding an AsyncTask - Android添加 AsyncTask - Android
【发布时间】:2012-04-02 05:50:52
【问题描述】:

我正在尝试将 AsyncTask 添加到以下类,但我不确定从哪里开始。如果可能的话,我想封装整个类。我是 Android 和 Java 的新手,所以我真的不知道自己在做什么。以下课程有效,我可以将所有信息正确发送到我的数据库。每次更新用户的位置时,程序首先在数据库中的一个表中检查用户 ID;如果它在表中不存在,则发送 GPS 坐标,但如果用户 ID 在表中,则不发送坐标并且程序停止发送位置更新。这就像它应该的那样工作,但是它锁定了我的 UI 并在尝试交互时抛出了 ANR 错误。我知道我需要实现一个 AsyncTask,但我需要一些指导。下面是该类的完整代码。任何帮助都会很棒!

public class FindLocation  {

protected static final Context SendLocation = null;
private LocationManager locManager;
private LocationListener locListener;

Context ctx;

public FindLocation(Context ctx) {
     this.ctx = ctx;
}
public void startLocation(final Context context, String usr_id2) { 

    final String usr = usr_id2;

    //get a reference to the LocationManager
    locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    //checked to receive updates from the position
    locListener = new LocationListener() {
        public void onLocationChanged(Location loc) {

            String lat = String.valueOf(loc.getLatitude()); 
            String lon = String.valueOf(loc.getLongitude());

            JSONArray jArray;
            String result = null;
            InputStream is = null;
            StringBuilder sb = null;

             ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
             nameValuePairs.add(new BasicNameValuePair("id", usr));

            //http post
            try{

                 HttpClient httpclient = new DefaultHttpClient();
                 HttpPost httppost = new HttpPost("http://www.example.com/test/example.php");     
                 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                 HttpResponse response = httpclient.execute(httppost);
                 HttpEntity entity = response.getEntity();
                 is = entity.getContent();
                 }catch(Exception e){
                     Log.e("log_tag", "Error in http connection"+e.toString());
                }

            //convert response to string
            try{
                  BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                   sb = new StringBuilder();
                   sb.append(reader.readLine() + "\n");

                   String line="0";
                   while ((line = reader.readLine()) != null) {
                                  sb.append(line + "\n");
                    }
                    is.close();
                    result=sb.toString();
                    }

                    catch(Exception e){
                          Log.e("log_tag", "Error converting result "+e.toString());                    
                    }
            try{
                  jArray = new JSONArray(result);
                  JSONObject json_data=null;
                  for(int i=0;i<jArray.length();i++){
                         json_data = jArray.getJSONObject(i);
                         String ct_name = json_data.getString("phoneID");
                         if(ct_name == usr) {
                             locManager.removeUpdates(locListener);
                         }
                     } 
                  }

                  catch(Exception e){
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost("http://example.com/test/example.php");

                        try {
                               List<NameValuePair> nameValuePairs1 = new ArrayList<NameValuePair>(2);
                               nameValuePairs1.add(new BasicNameValuePair("lat", lat)); 
                               nameValuePairs1.add(new BasicNameValuePair("lon", lon));
                               nameValuePairs1.add(new BasicNameValuePair("id", usr));
                               httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs1));
                               httpclient.execute(httppost);
                         } 
                         catch (ClientProtocolException g) {
                             // TODO Auto-generated catch block
                         } catch (IOException f) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } 
            } 
        }       


        public void onProviderDisabled(String provider){
        }
        public void onProviderEnabled(String provider){ 
        }
        public void onStatusChanged(String provider, int status, Bundle extras){
        }
    };
    locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000, 0, locListener);
}
}

【问题讨论】:

标签: java android class gps android-asynctask


【解决方案1】:

你应该做的就是:

  • 通过扩展 asynctask 修改 FindLocation 类
  • 更改 startLocation 以覆盖 doInBackground。

然后调用 asynctask 的 execute 方法而不是 startLocation。

另外,在您的情况下,异步任务可能不是最好的。通常你使用异步任务是因为你想在后台做一些事情,然后,当任务完成时,用后台操作的结果更新一些 ui 组件。在这里,由于您只需要在后台执行某些操作,但没有 UI 更新,因此您最好使用普通线程:

  • 让你类扩展线程
  • 更改 startLocation 以覆盖 run
  • 启动线程而不是调用 startLocation

--更新细节--

这可能更简单,但更熟悉 asyncTask 的想法也是一个不错的想法。

public class LocationFinder extends Thread {

  public LocationFinder( Context ctx ) {
   this.ctx = ctx;
  }

  public void start( String userId ) {
    this.userId = userId;
    super.start();
  }

  //defensive programming : prevent your thread from beeing started in an undesired way
  @Override 
  public void start() {
    throw new IllegalStateException( "LocationFinder can't be started using start(). Prefer start( int )." );
  }

  public void run() {
    //remaining of the code of startLocation except the first line.
  }

}

使用你的线程然后在一个活动中做:

new LocationFinder( this ).start( userId );

【讨论】:

  • 好的,这更有意义。您能否详细说明如何change startLocation for an override of run? 另外,我正在从我的主活动中调用 startLocation 并传递一个用户 ID,我将如何传递这个?我的主要活动到底是什么?谢谢
  • 将您的方法 startLocation 重命名为 public void run()。然后启动你的线程,实例化它并调用 start。
  • 那么我该如何从我的主要活动中调用它?
  • 不。然后定义一个方法 start( userId ) 并在将参数保存在数据成员中后从中调用 start() 。你的方法 run,因为它是一个覆盖,应该没有参数。
【解决方案2】:
 private class BackgroundLoader extends AsyncTask<Void, Void, Void> {
 private ProgressDialog dialog;
 protected Long doInBackground() {
    dialog = new ProgressDialog(ctx);
    dialog.show();
 }

 protected void doInBackground() {
     // do all your stuff here that doesn't modify the UI
 }

 protected void onPostExecute(Long result) {
    // do what you need to to the UI
    dialog.dismiss();
 }

然后在您的onCreate() 方法中创建实例调用new BackgroundLoader().execute();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    相关资源
    最近更新 更多