Issue
After many hours with searching for handling of NetworkOnMainThreadException
, I have used code from this video in YouTube
Very well explained but it doesn't in my project...
Then I have tried to use the solution from Stack Overflow (e.g. runOnUiThread, AsyncTask, Handler
) from following link:
https://stackoverflow.com/questions/3875184/cant-create-handler-inside-thread-that-has-not-called-looper-prepare
Currently I'm trying with AsyncTask again but the result is always the same- Exception: java.lang.RuntimeException:
Can't create handler inside thread Thread[AsyncTask #1,5,main] that has not called Looper.prepare()
The idea was to get datas from the class actualLottoNumbers over the method sendGet. It works with Eclipse but not with Android- I know now why but it works anyway not.
This is not a duplicate, because I have read the other questions since 3 days 10 times and tried every solution, but I think I have not really understood it.
Here is the code with AsyncTask
which doesn't work:
//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();
};
Full logcat:
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)
And here is the class from which I get the data for sendGet method in the activity with layout:
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;
} }
Solution
First of all you must not use AsyncTask in Activity, because you can create a memory leak. You should use AsyncTaskLoader in the Activity. But more elegant way is to use rxjava2 and retrofit2 for you needs.
The working code with AsyncTask bellow:
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;
}
}
}
Answered By - Matthew Strukov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.