【问题标题】:No solution works for handling of NetworkOnMainThreadException [closed]没有解决方案可用于处理 NetworkOnMainThreadException [关闭]
【发布时间】:2019-12-19 00:11:19
【问题描述】:

在搜索NetworkOnMainThreadException 处理数小时后,我使用了YouTube 中this 视频中的代码

很好解释,但它不在我的项目中...... 然后我尝试通过以下链接使用 Stack Overflow 的解决方案(例如runOnUiThread, AsyncTask, Handler):

https://stackoverflow.com/questions/3875184/cant-create-handler-inside-thread-that-has-not-called-looper-prepare

目前我再次尝试使用 AsyncTask,但结果始终相同 - 异常: java.lang.RuntimeException:

Can't create handler inside thread Thread[AsyncTask #1,5,main] that has not called Looper.prepare()

这个想法是通过方法 sendGet 从类 actualLottoNumbers 中获取数据。它适用于 Eclipse,但不适用于 Android - 我现在知道原因,但无论如何它都不起作用。

这不是重复的,因为我3天以来已经阅读了其他问题10次并尝试了每个解决方案,但我认为我还没有真正理解它。

这是带有AsyncTask 的代码,它不起作用:

//it doesn't matter the class Retrievdata is after or before onCreate method- it's always Exception
class Retrievedata extends AsyncTask<Void, Void, Void> {
    String var112="null";
    @Override
    protected Void doInBackground(Void... voids) {

        try {

            actualLottoNumbers var1 = new actualLottoNumbers();
            var112 = var1.sendGet("ff");
            while ((var1.sendGet("ff") != null)) {
                var112=var1.sendGet("ff");
            }



        } catch (MalformedURLException e) {
            e.printStackTrace();
            //var112= e.toString();
        } catch (Exception e) {
            e.printStackTrace();
            //var112= e.toString();
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void result) {

        setContentView(R.layout.activity_zufallsgenerator);
        TextView text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
        text_view_id1.setText(var112);

        //TextView text_prompt = (TextView) findViewById(R.id.text_prompt);
        //text_prompt.setText("Finished!");

        super.onPostExecute(result);
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_zufallsgenerator);

    text_prompt = (TextView) findViewById(R.id.text_prompt);
    text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
    bindViews();

    text_prompt.setText("wait...");

//Button for activity- generate numbers 

    mGenerateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            generateRandomNumbers();
        }
    });
   new Retrievedata().execute();
    text_prompt = (TextView) findViewById(R.id.text_prompt);
    text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
    bindViews();

};
   new Retrievedata().execute();
    text_prompt = (TextView) findViewById(R.id.text_prompt);
    text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
    bindViews();

};
   new Retrievedata().execute();
    text_prompt = (TextView) findViewById(R.id.text_prompt);
    text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
    bindViews();

};

完整的日志:

2019-08-12 14:10:55.893 25359-25456/com. W/System.err: java.lang.RuntimeException: Can't create handler inside thread Thread[AsyncTask #1,5,main] that has not called Looper.prepare()
    2019-08-12 14:10:55.893 25359-25456/com. W/System.err:     at android.os.Handler.<init>(Handler.java:205)
    2019-08-12 14:10:55.893 25359-25456/com. W/System.err:     at android.os.Handler.<init>(Handler.java:118)
    2019-08-12 14:10:55.894 25359-25456/com. W/System.err:     at android.app.Activity.<init>(Activity.java:831)
    2019-08-12 14:10:55.894 25359-25456/com. W/System.err:     at android.support.v4.app.SupportActivity.<init>(ComponentActivity.java:46)
    2019-08-12 14:10:55.894 25359-25456/com. W/System.err:     at android.support.v4.app.FragmentActivity.<init>(FragmentActivity.java:68)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at android.support.v7.app.AppCompatActivity.<init>(AppCompatActivity.java:62)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at com.generator23.actualLottoNumbers.<init>(actualLottoNumbers.java:15)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at com.generator23.Zufallsgenerator$Retrievedata.doInBackground(Zufallsgenerator.java:112)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at com.generator23.Zufallsgenerator$Retrievedata.doInBackground(Zufallsgenerator.java:105)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:333)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    2019-08-12 14:10:55.898 25359-25456/com. W/System.err:     at java.lang.Thread.run(Thread.java:764)

这是我从中获取带有布局的活动中的 sendGet 方法的数据的类:

public class actualLottoNumbers extends AppCompatActivity {


    private final String USER_AGENT = ("Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/30");
    private TextView textView1;


    // HTTP GET request
    public String sendGet(String var11) throws Exception {

        String url = "https://www....";

        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // optional default is GET
        con.setRequestMethod("GET");

        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);

        int responseCode = con.getResponseCode();


        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();


        //get the text from span class of the lotto
        String html=response.toString();
        Document doc = Jsoup.parse(html);
        Elements elements = doc.select("span.LottoBall__circle");
        for (Element e : elements) {
    //        System.out.println("Allt text:" + e.text());
     //       System.out.println("Only messageBody text:" + e.ownText()); var11=e.text();
        } return var11;

    } }

【问题讨论】:

  • 我建议您使用 okhttp 之类的东西,看看它很容易并且需要更少的 biolerplate square.github.io/okhttp
  • 最后有一个调用 new Retrievedata().execute()。为什么不使用?

标签: android asynchronous android-asynctask


【解决方案1】:

首先你不能在Activity中使用AsyncTask,因为你会造成内存泄漏。 您应该在 Activity 中使用 AsyncTaskLoader。 但更优雅的方法是根据需要使用 rxjava2 和 retrofit2。

AsyncTask 的工作代码如下:

public class MainActivity extends AppCompatActivity {
    private RetrieveData retrieveData;
    private TextView text_prompt;
    private TextView text_view_id1;
    private Button mGenerateButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text_prompt = (TextView) findViewById(R.id.text_prompt);
        text_view_id1 = (TextView) findViewById(R.id.text_view_id1);
        mGenerateButton = findViewById(R.id.mGenerateButton);

        mGenerateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                retrieveData = new RetrieveData();
                retrieveData.execute();
            }
        });
    }

    class RetrieveData extends AsyncTask<Void, Void, String> {
        String var112 = "null";

        @Override
        protected String doInBackground(Void... voids) {

            try {
                ActualLottoNumbers var1 = new ActualLottoNumbers();
                var112 = var1.sendGet("ff");
                while ((var1.sendGet("ff") != null)) {
                    var112 = var1.sendGet("ff");
                }
            } catch (Exception e) {
                e.printStackTrace();
                //var112= e.toString();
            }
            return var112;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            text_view_id1.setText(result);
        }
    }

    private class ActualLottoNumbers {
        private final String USER_AGENT = ("Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/30");
        private TextView textView1;

        // HTTP GET request
        public String sendGet(String var11) throws Exception {

            String url = "https://www....";

            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            // optional default is GET
            con.setRequestMethod("GET");

            //add request header
            con.setRequestProperty("User-Agent", USER_AGENT);

            int responseCode = con.getResponseCode();

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            //get the text from span class of the lotto
            String html = response.toString();

            return var11;
        }
    }
}

【讨论】:

    【解决方案2】:

    使actualLottoNumbers 类成为普通的Java 类而不是活动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 2023-01-16
      • 2010-12-31
      • 2013-02-18
      • 2023-03-25
      相关资源
      最近更新 更多