我在运行RssReader的Android项目时出错。

代码:

URL url = new URL(urlToRssFeed);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RssHandler theRSSHandler = new RssHandler();
xmlreader.setContentHandler(theRSSHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
return theRSSHandler.getFeed();

它显示以下错误:

android.os.NetworkOnMainThreadException

如何解决此问题?


当前回答

主线程是UI线程,您不能在主线程中执行可能会阻止用户交互的操作。您可以通过两种方式解决此问题:

强制在主线程中执行任务,如下所示

StrictMode.ThreadPolicy threadPolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(threadPolicy);

或者创建一个简单的处理程序并根据需要更新主线程。

Runnable runnable;
Handler newHandler;

newHandler = new Handler();
runnable = new Runnable() {
    @Override
    public void run() {
         try {
            //update UI
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
};
newHandler.post(runnable);

要停止线程,请使用:

newHandler.removeCallbacks(runnable);

有关更多信息,请查看:无痛线程

其他回答

简单地说,

不在UI线程中执行网络工作

例如,如果您执行HTTP请求,则这是一个网络操作。

解决方案:

您必须创建一个新线程或使用AsyncTask类

Way:

把你所有的作品放进去

新线程的run()方法或AsyncTask类的doInBackground()方法。

But:

当您从网络响应中获得一些内容并希望在视图中显示它(如在TextView中显示响应消息)时,需要返回到UI线程。

如果不执行此操作,将获得ViewRootImpl$CalledFromWrongThreadException。

如何

使用AsyncTask时,从onPostExecute()方法更新视图或者调用runOnUiThread()方法并更新run()方法内的视图。

截至2018年,我建议在Kotlin中使用RxJava进行网络获取。下面是一个简单的例子。

Single.fromCallable {
        // Your Network Fetching Code
        Network.fetchHttp(url) 
    }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe {
        // What you need to do with your result on the view 
        result -> view.updateScreen(result) 
    }

这个问题有两种解决方案。

不要在主UI线程中使用网络调用。为此使用异步任务。在setContentView(R.layout.activity_main)之后,将以下代码写入MainActivity文件:如果(android.os.Build.VERSION.SDK_INT>9){StrictMode.ThreadPolicy policy=new StrictMode.SthreadPolicy.Builder().permitAll().build();StrictMode.setThreadPolicy(策略);}

以及下面的import语句到Java文件中。

import android.os.StrictMode;

使用以下代码执行繁重的任务。

// Your package here


import java.util.List;
import org.apache.http.NameValuePair;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.view.View.OnSystemUiVisibilityChangeListener;

public class AsyncRequest extends AsyncTask<String, Integer, String> {

    Context context;
    ProgressDialog pDialog;

    // Three Constructors
    public AsyncRequest(Activity a, String m, List<NameValuePair> p) {
        context = a;
        method = m;
        parameters = p;
    }

    public AsyncRequest(Activity a) {
        this.caller = (OnAsyncRequestComplete) a;
        context = a;
    }

    public String doInBackground(String... urls) {

        //Perform your task here
        return result;
    }

    public void onPreExecute() {
        pDialog = new ProgressDialog(context);
        pDialog.setMessage("Please wait..");
        pDialog.setCancelable(false);
        pDialog.show();
    }

    public void onProgressUpdate(Integer... progress) {
        // You can implement some progressBar and update it in this record.
        //   setProgressPercent(progress[0]);
    }

    public void onPostExecute(String response) {
        if (pDialog != null && pDialog.isShowing()) {
            pDialog.dismiss();
        }
        // Get the result here
    }

    protected void onCancelled(String response) {

        if (pDialog != null && pDialog.isShowing()) {
            pDialog.dismiss();
        }
    }
}

在Android上,网络操作不能在主线程上运行。您可以使用线程、异步任务(短期运行任务)和服务(长期运行任务)来执行网络操作。