android.os.NetworkOnMainThreadException。怎么解决?

时间:2014-04-26 01:38:34

标签: android google-maps locationmanager

我正在尝试获取当前位置并获取前往某个目的地的行车路线。 我能够获得我的位置,当我执行行车路线的代码时,我会在以下行中获得android.os.NetworkOnMainThreadException

        HttpResponse response = httpClient.execute(httpPost, localContext);

响应为NULL。我该怎么办?

public Document getDocument(LatLng start, LatLng end, String mode) {
    String url = "http://maps.googleapis.com/maps/api/directions/xml?" 
            + "origin=" + start.latitude + "," + start.longitude  
            + "&destination=" + end.latitude + "," + end.longitude 
            + "&sensor=false&units=metric&mode="+mode;

    try {
         new DownloadWebpageTask().execute(url);


        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
        HttpResponse response = httpClient.execute(httpPost, localContext);
        InputStream in = response.getEntity().getContent();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(in);
        return doc;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

3 个答案:

答案 0 :(得分:1)

NetworkOnMainThreadException所述,网络请求应仅在后台线程中执行。你无法在主线程中执行。

创建AsycTask并在doInBackground()方法上执行代码。后台操作完成后,您可以在onPostExecute

中更新用户界面
 new AsyncTask<Void, Integer, Document>(){
        @Override
        protected Document doInBackground(Void... params) {
            try {

                // call you method here
                return getDocument();

            } catch (Exception ex) {
                // handle the exception here
            }
            return null;
        }

        @Override
        protected void onPostExecute(Document result){
            // update the UI with your data
        }
    }.execute();

答案 1 :(得分:0)

您无法在主UI线程上执行网络操作。你需要做的是创建一个新的线程并在那里做网络的东西。如果需要,您可以使用Handler将更新发布回主UI线程。如果您需要代码示例,我可以发布一个应该有效的最小代码。

执行此操作时,重要的是不要将强引用保留回活动,否则您可能会泄漏设备旋转或其他onDestroy()事件的整个活动。因为您已将Context传递给其他线程,所以您需要对此进行测试以确保您不会泄露。我在Tumblr上写了一篇关于此的博文:

http://tmblr.co/ZSJA4p13azutu


编辑1

这里有一些应该有用的代码:

static final class ProgressMessages extends Handler
{
    private WeakReference<MyAndroidClass> weakAndroidClassRef;

    public ProgressMessages (MyAndroidClass myContext)
    {
        weakWritingPadRef = new WeakReference<MyAndroidClass>( myContext);

    }

    public void handleMessage(Message msg)
    {
        String s = "Uploading page " + msg.arg1 + ".";
        Toast t = Toast.makeText(weakAndroidClassRef.get(), s, Toast.LENGTH_LONG);
        t.show();   

    }


};

ProgressMessages pm;



public void doNetworkStuff()
{

    t = new Thread()
    {
        public void run()
        {

             Looper.prepare();
             try
             {
                  pm.sendMessage(Message.obtain(pm, 0, i + 1, 0));


             }
             catch(IOException ioe)
             {
                 ioe.printStackTrace();

             }
             pm.post(update);
        }


    };
    t.start();

}

答案 2 :(得分:0)

这是因为当您尝试在主线程上进行网络连接时...应该在后台线程上完成..

<强>溶液: 的AsyncTask

点击此处了解AsyncTask