【问题标题】:how to use method in AsyncTask in android?如何在android的AsyncTask中使用方法?
【发布时间】:2012-12-02 07:03:07
【问题描述】:

在我的应用程序中,我使用JSON webservice 从Google Navigation api 获取数据。我使用的代码如下。 我得到了以下异常

android.os.NetworkOnMainThreadException.

如何使用AsyncTask?这是我的代码。谢谢。`public class MainActivity extends MapActivity {

  MapView mapView ;

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    System.out.println("*************1**************1");
    setContentView(R.layout.activity_main);
    System.out.println("*************2**************");
    mapView = (MapView) findViewById(R.id.mapv); 
    System.out.println("*************3**************");



                Route route = directions(new GeoPoint((int)(26.2*1E6),(int)(50.6*1E6)), new GeoPoint((int)(26.3*1E6),(int)(50.7*1E6)));

              RouteOverlay routeOverlay = new RouteOverlay(route, Color.BLUE);
              mapView.getOverlays().add(routeOverlay);
            mapView.invalidate();


    System.out.println("*************4**************");

}



@SuppressLint("ParserError")
private Route directions(final GeoPoint start, final GeoPoint dest) {



    //https://developers.google.com/maps/documentation/directions/#JSON <- get api
    String jsonURL = "http://maps.googleapis.com/maps/api/directions/json?";
    final StringBuffer sBuf = new StringBuffer(jsonURL);
    sBuf.append("origin=");
    sBuf.append(start.getLatitudeE6()/1E6);
    sBuf.append(',');
    sBuf.append(start.getLongitudeE6()/1E6);
    sBuf.append("&destination=");
    sBuf.append(dest.getLatitudeE6()/1E6);
    sBuf.append(',');
    sBuf.append(dest.getLongitudeE6()/1E6);
    sBuf.append("&sensor=true&mode=driving");

    Parser parser = new GoogleParser(sBuf.toString());
      Route   r =  parser.parse();
   System.out.println("********r in thread*****" +r);                  
            return r;
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}

} `

【问题讨论】:

  • Android 不使用 Google Maps API V3。 (已删除标签)

标签: android google-maps driving-directions


【解决方案1】:

@imran khan 使用另一个线程的想法是正确的。在 HoneyComb 及以上版本中,您无法在 UI Thread 内进行任何联网操作。 UI 线程是负责显示视图和接收触摸事件的线程,它必须是空闲的,不能被长时间运行的操作阻塞。 (否则你会在 Android 上遇到 ANR)。

但实际上,将 AsyncTask 用于网络请求等长时间运行的操作并不是一个好主意。 AsyncTask javadocs 甚至声明它们是为短期运行而设计的......

最好的方法是为此使用服务。我鼓励您从 RoboSpice 库中阅读此 infographics 并使用 RoboSpice,它将简化通过网络创建服务,并使您更容易使用 Spring Android 解析您的 json 内容。

【讨论】:

  • 很棒的反应!感谢分享!
  • 谢谢。我确实犹豫在这里发布信息图表,但它看起来很有帮助;)
【解决方案2】:

您可以将使用 Web 服务获取数据的代码放在 AsyncTask 类的 doInBackground() 方法中,并从该函数返回结果。它将进入 onPostExecute() 方法,您可以在那里解析和更新您的 UI。

private class myasyncclass extends AsyncTask<String, Void, Route>{
    @Override
    protected Route doInBackground(String... params) {
        //Enter code for fetching data from remote server using webservice
        return yourRoutevalue;
    }
    @Override
    protected void onPostExecute(Route result) {   
        //Enter code for parsing and using the data(Update UI)
    }
}

您应该在 AsyncTask(DoInBackground, Progress, OnPostExecute) 中具有相同的类型

【讨论】:

    【解决方案3】:

    将您的代码更改为使用 AsyncTask:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    //Your Code here
    new LongOperation().execute("");
    
    System.out.println("*************4**************");
    
    }
    
    private class LongOperation extends AsyncTask<String, Void, String> {
    
          @Override
          protected Route  doInBackground(String... params) {
             Route route;
            try {
                route = directions(new GeoPoint((int)(26.2*1E6),
                   (int)(50.6*1E6)), new GeoPoint((int)(26.3*1E6),(int)(50.7*1E6)));
    
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
                return Route ;
          }      
    
          @Override
          protected void onPostExecute(Route  route) {    
            // Update Ui here    
               RouteOverlay routeOverlay = new RouteOverlay(route, Color.BLUE);
               mapView.getOverlays().add(routeOverlay);
               mapView.invalidate();       
          }
    
    }
    

    注意:如果您将任何值从 UI 元素传递给 HTTP REQUEST,那么您必须将其作为参数传递给 AsyncTask 的 doInBackground 方法。您可以在此处查看我们如何将参数传递给 AsyncTask:

    http://developer.android.com/reference/android/os/AsyncTask.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多