App crashes while can't perform AsyncTask - java

I have a problem with AsyncTask in my app. AsyncTask is located in SplashScreenAcivity.java. It downloads data using json for MainActivity.java while showing splash screen. When data is loaded, app shows MainActivity screen. However, when i turn off internet connection app crashes. Instead of it i would like to move to MainActivity.java and show toast that internet connection must be turned on. SplashScreen.java loads data for listView in MainActivity.
SplashActivityScreen.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new DownloadData().execute();
}
private class DownloadData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
SyncHttpClient clientOne = new SyncHttpClient();
clientOne.get("https://api.themoviedb.org/3/tv/top_rated?api_key=d253f520df9cd868af7db8daaa0db8fb&language=en-US", new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
try {
tvseries0 = response.getJSONArray("results").getJSONObject(0).getString("name");
tvseries1 = response.getJSONArray("results").getJSONObject(1).getString("name");
tvseries2 = response.getJSONArray("results").getJSONObject(2).getString("name");
tvseries3 = response.getJSONArray("results").getJSONObject(3).getString("name");
tvseries4 = response.getJSONArray("results").getJSONObject(4).getString("name");
tvseries5 = response.getJSONArray("results").getJSONObject(5).getString("name");
tvseries6 = response.getJSONArray("results").getJSONObject(6).getString("name");
tvseries7 = response.getJSONArray("results").getJSONObject(7).getString("name");
tvseries8 = response.getJSONArray("results").getJSONObject(8).getString("name");
tvseries9 = response.getJSONArray("results").getJSONObject(9).getString("name");
tvseries10 = response.getJSONArray("results").getJSONObject(10).getString("name");
tvseries11 = response.getJSONArray("results").getJSONObject(11).getString("name");
tvseries12 = response.getJSONArray("results").getJSONObject(12).getString("name");
tvseries13 = response.getJSONArray("results").getJSONObject(13).getString("name");
tvseries14 = response.getJSONArray("results").getJSONObject(14).getString("name");
tvseries15 = response.getJSONArray("results").getJSONObject(15).getString("name");
tvseries16 = response.getJSONArray("results").getJSONObject(16).getString("name");
tvseries17 = response.getJSONArray("results").getJSONObject(17).getString("name");
tvseries18 = response.getJSONArray("results").getJSONObject(18).getString("name");
tvseries19 = response.getJSONArray("results").getJSONObject(19).getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers,Throwable e , JSONObject response) {
Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();
}
});
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.putExtra("tvseries0", tvseries0);
i.putExtra("tvseries1", tvseries1);
i.putExtra("tvseries2", tvseries2);
i.putExtra("tvseries3", tvseries3);
i.putExtra("tvseries4", tvseries4);
i.putExtra("tvseries5", tvseries5);
i.putExtra("tvseries6", tvseries6);
i.putExtra("tvseries7", tvseries7);
i.putExtra("tvseries8", tvseries8);
i.putExtra("tvseries9", tvseries9);
i.putExtra("tvseries10", tvseries10);
i.putExtra("tvseries11", tvseries11);
i.putExtra("tvseries12", tvseries12);
i.putExtra("tvseries13", tvseries13);
i.putExtra("tvseries14", tvseries14);
i.putExtra("tvseries15", tvseries15);
i.putExtra("tvseries16", tvseries16);
i.putExtra("tvseries17", tvseries17);
i.putExtra("tvseries18", tvseries18);
i.putExtra("tvseries19", tvseries19);
startActivity(i);
finish();
}
}
}
Crash 1
04-30 13:15:35.165 12349-12365/przemo.me.recommend.recommendme E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: przemo.me.recommend.recommendme, PID: 12349
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at com.loopj.android.http.AsyncHttpResponseHandler.onUserException(AsyncHttpResponseHandler.java:304)
at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:395)
at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401)
at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319)
at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109)
at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95)
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078)
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:346)
at android.widget.Toast.<init>(Toast.java:101)
at android.widget.Toast.makeText(Toast.java:260)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData$1.onFailure(SplashScreenActivity.java:103)
at com.loopj.android.http.JsonHttpResponseHandler.onFailure(JsonHttpResponseHandler.java:233)
at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:359)
at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401) 
at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319) 
at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109) 
at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95) 
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078) 
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037) 
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64) 
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56) 
at android.os.AsyncTask$2.call(AsyncTask.java:304) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
Crash 2
04-30 13:15:35.162 12349-12365/przemo.me.recommend.recommendme E/AsyncHttpRH: User-space exception detected!
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:346)
at android.widget.Toast.<init>(Toast.java:101)
at android.widget.Toast.makeText(Toast.java:260)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData$1.onFailure(SplashScreenActivity.java:103)
at com.loopj.android.http.JsonHttpResponseHandler.onFailure(JsonHttpResponseHandler.java:233)
at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage(AsyncHttpResponseHandler.java:359)
at com.loopj.android.http.AsyncHttpResponseHandler.sendMessage(AsyncHttpResponseHandler.java:401)
at com.loopj.android.http.AsyncHttpResponseHandler.sendFailureMessage(AsyncHttpResponseHandler.java:319)
at com.loopj.android.http.AsyncHttpRequest.run(AsyncHttpRequest.java:109)
at com.loopj.android.http.SyncHttpClient.sendRequest(SyncHttpClient.java:95)
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1078)
at com.loopj.android.http.AsyncHttpClient.get(AsyncHttpClient.java:1037)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:64)
at przemo.me.recommend.recommendme.SplashScreenActivity$DownloadData.doInBackground(SplashScreenActivity.java:56)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

You can not do UI operations from non UI thread. Like in your code you are showing Toast in Async task thread.
You should replace
Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();
with this
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();
}
});

use -
SplashScreenActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(SplashScreenActivity.this, "Turn on the internet and swipe to refresh.", Toast.LENGTH_SHORT).show();
}
});

Here is a server connection AsyncTask task that I created years ago in Android Java. The background task works successfully. I used it to update in the background the data repository in the App I developed at that time.
public class DataExchangeStore extends Application {
public void startServerConnection(Context contextGlobal, Activity activityGlobal) {
this.contextGlobal = contextGlobal;
this.activityGlobal = activityGlobal;
connectTask = new ConnectTask();
connectTask.execute("");
}
private ConnectTask connectTask;
public class ConnectTask extends AsyncTask<String, String, TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_BACKGROUND);
// we create a TCPClient object
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
#Override
// here the messageReceived method is implemented
public void messageReceived(ChatMessage message) {
// this method calls the onProgressUpdate
publishProgress(message.getMessage());
}
}, contextGlobal, activityGlobal);
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
System.err.println(values[0]);
// do your stuff here
}
}
Import is to permanently lock the screen orientation of the activity, specifying the screenOrientation attribute in the Android-Manifest file with portrait or landscape values:
<activity android:screenOrientation="portrait" />

Although previous answers are not wrong, using runOnUiThread() to jump out of the background thread in the AsyncTask is not a good practice. You have the onPostExecute() method for that.
What you should be doing is passing a result object to onPostExecute(). This object would encapsulate the result state (ie: error or success) and the actual data received. Then in onPostExecute() you check the result state and display a Toast if the state is error.
And do yourself a favor and replace your 20 TvSerie objects by a List<TvSerie> and do a loop in you AsyncTask to populate the list.
Please refer to the AsyncTask documentation for details on how to properly use it.

Related

Out of bounds exception when confirming a user

I am trying to set up AWS Cognito email verification for my app. However, when the email verification number is typed in and the user clicks the verify button, I keep getting a
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
I understand what this means however I am learning as I go, so I am struggling to find exactly where the issue is made.
I have already researched the issues over Stack Overflow and have not found any help directly relating to this issue and amazon cognito. I have tried adjusting the array size and tried to make different catch senerios to see where the code goes wrong.
Here is the Java file that the error comes from
public class verify extends AppCompatActivity {
private static final String TAG = "Cognito";
private CognitoUserPool userPool;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify);
final EditText verifyCode = findViewById(R.id.verifyCode);
Button verifyButton = findViewById(R.id.verifyButton);
verifyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new ConfirmTask().execute(String.valueOf(verifyCode.getText()));
Intent intent = new Intent(verify.this, stepTwo.class);
startActivity(intent);
}
});
}
protected class ConfirmTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
final String[] result = new String[1];
final GenericHandler confirmationCallback = new GenericHandler() {
#Override
public void onSuccess() {
result[0] = "Successful!";
}
#Override
public void onFailure(Exception exception) {
result[0] = "Failed " + exception.getMessage();
}
};
CognitoSettings cognitoSettings = new CognitoSettings(verify.this);
CognitoUser thisUser = cognitoSettings.getUserPool().getUser(strings[1]);
thisUser.confirmSignUp(strings[0], false, confirmationCallback);
return result[0];
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
Log.i(TAG, "Confirmation result: " + result);
}
}
}
I expect the app to not crash and for the Amazon Cognito User Pool to show that I have verified the email.
Here is my logcat
2019-09-04 18:02:51.418 18206-19048/com.example.medicut E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.medicut, PID: 18206
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$4.done(AsyncTask.java:399)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
at com.example.medicut.verify$ConfirmTask.doInBackground(verify.java:64)
at com.example.medicut.verify$ConfirmTask.doInBackground(verify.java:41)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
at java.lang.Thread.run(Thread.java:919) 

Android app is crashing with An error occurred while executing doInBackground()

Not able to set the data in the database in server...getting values from editText and passing them in doBackground() but error occured while executing in background...any help will be appreciated...thanx in advance...log added......
Here is the log
9 10:27:05.333 3245-3523/com.amar.schooladmin E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #7
Process: com.amar.schooladmin, PID: 3245
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:703)
at android.widget.Toast.<init>(Toast.java:145)
at android.widget.Toast.makeText(Toast.java:458)
at com.amar.schooladmin.AddRecord$CreateNewProduct.doInBackground(AddRecord.java:77)
at com.amar.schooladmin.AddRecord$CreateNewProduct.doInBackground(AddRecord.java:61)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
01-19 10:27:0
MainActivity.java
button7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new CreateNewProduct().execute();
roll=editText.getText().toString();
name=editText2.getText().toString();
address=editText3.getText().toString();
fname=editText4.getText().toString();
mname=editText5.getText().toString();
}
});
}
public class CreateNewProduct extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... strings) {
List<NameValuePair> parms = new ArrayList<>();
parms.add(new BasicNameValuePair("roll", roll));
parms.add(new BasicNameValuePair("name", name));
parms.add(new BasicNameValuePair("address", address));
parms.add(new BasicNameValuePair("fname", fname));
parms.add(new BasicNameValuePair("mname", mname));
JSONObject jsonObject = jsonParser.makeHttpRequest(url, "POST", parms);
try {
int success= jsonObject.getInt("TAG SUCCESSFULLY");
} catch (Exception e) {
Toast.makeText(AddRecord.this, ""+e.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
The problem is you are showing Toast in doInBackground(). try this
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(AddRecord.this, ""+e.toString(), Toast.LENGTH_SHORT).show();
}
});
You can't write show() method of Toast in doInBackground() because it is not UI thread it is worker thread. You can write Toast in onPostExecute().
Toast is causing the crash to occur, because Toast requires UI Thead to display and currently it is in background thread.
Also, you are getting exception at
int success= jsonObject.getInt("TAG SUCCESSFULLY");
and hence in catch Toast line is getting executed.
Please check if TAG SUCCESSFULLY key exists in jsonObject or not. Use
if(jsonObject.has("TAG SUCCESSFULLY"))
success= jsonObject.getInt("TAG SUCCESSFULLY");

Jsoup html display in webview not working

I am working on an android app in android studio, the app pulls some data from amazon and displays it in a webview.
For some reason the webview remains blank, I have tested my code in a standard java project using eclipse. The Jsoup code is good and runs clean in eclipse but in android studio it also shows no errors with the exception of no webview.
Here is my Code
public class showdata extends AppCompatActivity {
WebView firstresault;
public String amazonproduct;
public Element productamazon;
public class getres extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... params) {
try {
Document doc = Jsoup.connect("https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=841351100182").get();
productamazon = doc.select("div#s-item-container").first();
amazonproduct = productamazon.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
WebView wview = (WebView)findViewById(R.id.amazon_product);
wview.loadData( amazonproduct, "text/html", null);
Log.i("amazonproduct", "Null or Not");
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showdata);
new getres();
}
}
I am new to the android api so I am sure that it is something simple. All help is appreciated!
logcat
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.rober.shoppingappbarcode, PID: 11086
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:318)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.jsoup.nodes.Element.toString()' on a null object reference
at com.example.rober.shoppingappbarcode.showdata$getres.doInBackground(showdata.java:28)
at com.example.rober.shoppingappbarcode.showdata$getres.doInBackground(showdata.java:20)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
you need to execute your AsyncTask using execute() function call
new getres().execute();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showdata);
new getres().execute();
// ^^^^^^^
}
Try using this
productamazon = doc.getElementsByClass("s-item-container").first();
instead of this
productamazon = doc.select("div#s-item-container").first();

SocketTimeoutException crashing AsyncTask in Android 4.x

I'm having trouble with the case where a SocketChannel.connect times out. The code bellow works fine in my old Android 2.3 phone and my old Android 3.2 tablet but crashes in Android 4.2.2:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvResult = (TextView) findViewById(R.id.tvResult);
btnTest = (Button) this.findViewById(R.id.btnTest);
btnTest.setOnClickListener(doTest);
}
protected View.OnClickListener doTest = new View.OnClickListener() {
#Override
public void onClick(View v) {
new AsyncTest().execute();
}
};
private class AsyncTest extends AsyncTask {
private String result = "";
#Override
protected Void doInBackground(Void... params) {
InetSocketAddress addr = new InetSocketAddress("192.168.0.13", 4040);
boolean bConnect = false;
try {
SocketChannel clntChan = SocketChannel.open();
bConnect = clntChan.connect(addr);
if (bConnect) {
clntChan.close();
result = "Connected";
} else {
result = "Did not connected";
}
} catch (Exception e) {
Log.e(TAG, "Exception " + e.getMessage());
result = "Exception " + e.getMessage();
}
return null;
}
#Override
protected void onPostExecute(Void ret) {
tvResult.setText (result);
}
}
I am testing the case where there is no one is listening on port 4040 at 192.168.0.13. In Android 2.3 the try/catch will catch a "Connection timeout" exception (as expected). In Android 4.x I get the following:
FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
Caused by: java.lang.AssertionError: java.net.SocketTimeoutException: failed to connect to /192.168.0.13 (port 4040) after 90000ms
at libcore.io.IoBridge.connect(IoBridge.java:102)
at java.nio.SocketChannelImpl.connect(SocketChannelImpl.java:177)
at br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:63)
at br.com.dqsoft.testeconnect.MainActivity$AsyncTest.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
... 4 more
Caused by: java.net.SocketTimeoutException: failed to connect to /192.168.0.13 (port 4040) after 90000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:176)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at libcore.io.IoBridge.connect(IoBridge.java:100)
... 9 more
A could not find a way to catch this exception, the app is closed by the OS. While a timeout is not a normal condition, I should be able to detect that and present an error message to the user instead of just crashing.
The case where the connect succeeds works fine in all the devices.
Edit: The initial paragraph erroneously mentioned Android 2.4 instead of 4.2.2.
Edit: Simplified the code as suggest by Jarred and added additional information.
Update: Tested on a Android 4.4.4 device and it worked. I will close this as a bug of Android 4.2.2 (maybe on this specific device).
Remove most of this:
You are starting a Thread from a Thread form another Thread. Just start a single Thread from your Main Thread, using your AsyncTask.
protected View.OnClickListener doTest = new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new threadTest()).start();
}
};
private class threadTest implements Runnable {
#Override
public void run() {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
new AsyncTest().execute();
}
});
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
}
Change it to:
protected View.OnClickListener doTest = new View.OnClickListener() {
#Override
public void onClick(View v) {
new AsyncTest().execute();
}
};
For the Exception and Timeout:
IOException is the parent class of SocketTimeoutException, so your AsyncTask code should work. When in doubt, you can catch everything by using Exception.
Other things to check:
Can you ping 192.168.0.13?
How do you know that port is open? Try telnet or netcat.
Do you have a service running and configured correctly on the port?
Do you have the correct Android Permissions?

AsyncTask Class Runtime Error : concurrent.FutureTask.finishCompletion

i m new in android and trying to make simple program that can print variable in AsyncTask Class
here is my code
int a,b,c;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
a =10;
b=10;
c=a+b;
Context ctx = null;
show(c, ctx );
return null;
}
public void show(int c2 ,Context c) {
// TODO Auto-generated method stub
Toast.makeText(c, "AsyncTask classs + c2 ", Toast.LENGTH_SHORT).show();
}
after running this program , i m getting run time Error
here us LogCat file view
Process: com.example.asycclass, PID: 2539
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:327)
at android.widget.Toast.<init>(Toast.java:92)
at android.widget.Toast.makeText(Toast.java:241)
at com.example.asycclass.MainActivity$AttemptLogin.show(MainActivity.java:74)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:65)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
Move your show Toast code inside runOnUiThread like :
runOnUiThread(new Runnable() {
#Override
public void run() {
show(c, ctx );
}
});
I guess that the problem is that you're trying to create a Toast not from the main thread.
You must create a handler and Runnable for that and use handler.post()
For example
Runnable showToast = new Runnable() {
public void run() {
// Create your Toast here or whatever you want
}
}

Categories

Resources