Android AsyncTask (returning an Integer from doInBackground) - android

I'm getting the following errors in the code below: The return type is incompatible with AsyncTask.onPostExecute(Integer). I'm trying to return the result from the http request done in the doInBackground task. I get the error: Type mismatch: cannot convert from AsyncTask to int in the return statement for isAvailable. I feel like there's something simple I'm not doing but I can't quite figure it out.
public int isAvailable(int position) {
GetIsAvailable isAvail = new GetIsAvailable();
Integer nisAvail = isAvail.execute(position); // error is still here
return nisAvail;
}
private class GetIsAvailable extends AsyncTask<Integer,Void,Integer > {
#Override
protected Integer doInBackground(Integer...position) {
Bundle resBundle = new Bundle();
String url = "http://www.testurl.com"
+ position[0]+"&uname="+AppStatus.mUserName;
URL iuri;
try {
iuri = new URL(url);
URLConnection connection = iuri.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-type",
"application/x-www-form-urlencoded");
BufferedReader br = new BufferedReader(new InputStreamReader(
(InputStream) connection.getContent()));
resBundle.putInt("isAvail", Integer.parseInt(br.readLine().trim()));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Integer(0);
}
#Override
protected Integer onPostExecute(Integer isAvail) { // Main Error here
return isAvail;
}

Oh, I think I see the problem. I don't think you can handle this the way you're doing it currently. You should be handling the effects of the value of isAvail within the onPostExecute() method. isAvailable() is running on the main thread, while isAvail is running on a separate thread. You're trying to return the result of the AsyncTask before it has finished completion.
I'm 99% sure that's the problem.

I believe what you're looking for is
Integer nisAvail = isAvail.execute(position).get();
but then the task is no longer asynchronous as the UI thread has to wait until the AsyncTask finishes.
If you want to keep it asynchronous then you have to handle the result in onPostExecute.

This return an int:
return Integer.parseInt(br.readLine().trim());
this return an int as well:
return 0;
You must return an Integer:
return new Integer(br.readLine().trim());
return new Integer(0);

If you want to get value returned from doInBackground method.
Then do this:
Integer Value = AsyncTaskClass.execute(ParamsIfSpecified).get();

Related

Strange behaviour when receiving data

I'm developing an Android app that requires me to get some data from the server, this data is comes as JSON data, I have to receive like 7 JSON Objects, I'm using regular socket programming to get this data, and I get it by launching a thread that will wait for a data to come from the server.
I'm using the following method:
public String getServerRespons() throws JSONException {
String responseLine, server_response = null_string;
try {
input = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
} catch (IOException e) {
}
int count = 0;
boolean first = true;
try {
while (true)
{
if((responseLine = input.readLine()) == null){
break;
}
first = false;
server_response = server_response + responseLine;
//
// some processing to make sure it's a valid JSON
//
if(count == 0){ // related to the Processing Lines result
System.out.println(server_response);
return response; // when commenting that line everything is ok
}
}
} catch (IOException e) {
Login.errorMessage.setText(conn_err);
}
return null;
}
With that way i got like only two or three JSON Objects of the seven ones. BUT, when commenting the return Line and let it completes with the receiving process I got all the seven Objects efficiently and each Object is separated which makes me make sure that the processing i made to validate the JSON is going so well.
I think int count is always 0 in your example so the return statement is always hit.

AsyncTask hangs on at beginning

AsyncTask works fine in Android 4.x, but not for Android 2.3.6. I've step-by-step debugged Android 2.3.6 with a physical mobile device.
It hangs on here:
myTask = new GetDataFromServer();
GetDataFromServer is the class of AsyncTask.
What's going on?
Here under is my code, I only used 1 AsyncTask in my code and received messages from server.
that's all.
class GetDataFromServer extends AsyncTask<String, String, String>
{
protected void onPreExecute ()
{
progressDialog1=ProgressDialog.show(MainActivity.this, "Loading data", "Please wait...",true);
}
protected String doInBackground(String... params)
{
String resulttxt="";
try {
serverIp = InetAddress.getByName("192.168.1.123");
int serverPort=31000;
Socket clientSocket=new Socket(serverIp,serverPort);
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
bw.write(params[0]);
bw.flush();
BufferedReader br=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
resulttxt=br.readLine();
if(resulttxt.contains("OK"))
{
publishProgress(resulttxt);
}
else
{
publishProgress(resulttxt);
clientSocket.close();
bw.close();
br.close();
return null;
}
resulttxt="";
resulttxt=br.readLine();
resulttxt=resulttxt.trim();
clientSocket.close();
} catch (IOException e) {
if(Status_txt!=null)
Status_txt.append( "Server is done.");
}
catch (NetworkOnMainThreadException e){
if(Status_txt!=null)
Status_txt.append( "NetworkOnMainThreadException");
}
return resulttxt;
}
protected void onProgressUpdate(String...inStr){
String[] strData=inStr[0].split("_");
String szTemp="Last Purchase Date: ";
szTemp+=strData[1];
szTemp+=" ,Valid days: ";
szTemp+=strData[2];
//Status_txt.setText(szTemp);
if(Status_txt!=null)
Status_txt.setText("You Are The Super User");
}
protected void onPostExecute(String data) {
tl_prediction2.removeAllViews();
if (data == null)
{
}
else {
if((data.contains("#")==true) || (data.contains("*")==true)
||data.contains("&")==true)
{
String[] arrayTmp=data.split("#");
for(Integer i=0;i<arrayTmp.length;i++)
{
String[] SubArrayTmp=arrayTmp[i].split("_");
tl_prediction2.addView(generateRow(4,SubArrayTmp));
}
}
}
progressDialog1.dismiss();
}
};
Since you haven't posted any code, I could only give you some random probable solutions:
May be your AsyncTask is taking a lot of time to download. Trying increasing its priority using android.os.Process.setThreadPriority(9) inside doInBackground()
Check if you have other previous running long AsyncTask in your code. AsyncTask by default operates on a single background thread. That means your AsyncTask task wouldn't be executed unless your previous AsyncTask are done. To allow parallel execution use executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params). You can read more here
Check for Internet and other permissions in Manifest. This is mostly where people make mistake.
AsyncTask works with ThreadPool. If there too many synctasks are executing, the later AsyncTask will be blocked by others. I think you can use the thread tool in DDMS to check the How many ayncTasks are executing.

Http Response inside a service in Android

Hi I have a service in Android that handles the HTTP method POST as specified below. Now, I need to call an Intent in
replaceResourceSegment()
method. It has a handler that takes nearly 90 seconds to complete the task. Within that time, control exits the handler block. But I want my program to continue within handler for POST. In short, I want my service to pause for sometime inside the POST handler, till my Intent (with handler) completes its execution and I need to delay sending the response of HTTP Post. Can some one guide me how to do this implementation?
if(method.equals("POST"))
{
conn.receiveRequestEntity((HttpEntityEnclosingRequest)request);
HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
String content_type = ""+entity.getContentType();
JSONReceived = EntityUtils.toString(entity);
if(content_type.contains("json"))
{
Log.d(TAG,"Content received is: "+JSONReceived);
bufferedWriter = new BufferedWriter(new FileWriter(new File(getFilesDir()+File.separator+constants.UPDATED_SCRIPT_FILE)));
bufferedWriter.write(JSONReceived);
bufferedWriter.close();
try {
parseJSON(JSONReceived);
replaceResourceSegment(); //Call to an intent with startActivityForResult()
continueExecution(); //Continue the execution from here
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG,"IOException line 157");
}
Code for sending response back:
HttpResponse postResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
postResponse.setEntity(new StringEntity("Got it"));
conn.sendResponseHeader(postResponse);
conn.sendResponseEntity(postResponse);
I managed to solve the problem by using a boolean variable with default value false. It will be checked periodically and keeps the control inside the POST method's handler.
android.os.SystemClock.sleep(30000); //Sleeps for 30 seconds and invoke busy waiting in a thread
Thread syncThread = new Thread(new LoopCheck());
syncThread.start();
synchronized(syncThread)
{
Log.d(TAG,"Inside synchronized blockk");
try
{
syncThread.wait();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
The thread class is defined as below:
class LoopCheck extends Thread{
public LoopCheck(){
}
public void run(){
while(true)
{
try {
Thread.sleep(10000);
if(write)
{
write = false;
synchronized(syncThread)
{
syncThread.notify();
}
break;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Android stop download

In my application I download and parse a html page. However, I want to be able to stop the download in its tracks (i.e. when the user hits cancel).
This is the code I use now, which is being called from doInBackground from ASyncTask.
How do I cancel this request from outside of the ASyncTask?
I currently use htmlcleaner
HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties props = cleaner.getProperties();
props.setAllowHtmlInsideAttributes(true);
props.setAllowMultiWordAttributes(true);
props.setRecognizeUnicodeChars(true);
props.setOmitComments(true);
try {
URL url = new URL(urlstring);
URLConnection conn = url.openConnection();
TagNode node = cleaner.clean(new InputStreamReader(conn.getInputStream()));
return node;
} catch (Exception e) {
failed = true;
return;
}
Can't you use AsyncTask.cancel()? You should be able to then use the onCancelled callback to return to the main activity..
Ok, I believe I've solved this.
In my Activity class I have a variable (boolean) failed. Also, I have a private Downloader class within the activity which extends ASyncTask. This way, the Downloader class has access to the failed boolean. When the Activity launches, it starts the Downloader task and a progress dialog pops up. When the task finishes, it closes the dialog and then goes on processing the downloaded content.
However, when the user cancels the progress dialog, failed is set to true, and the user is sent back to the previous activity by a call to finished. In the meantime, Downloader is still busy downloading. Because the results are now unneccessary, we want it to stop using resources asap. In order to accomplish this, I have broken up the doInBackground method in as much steps as possible. After each step I check if failed is still false, when it is set to true, it simply doesn't go to the next step. See it in action below. Furthemore, the BufferedReader reader is public, and in the onCancelled method I execute reader.close(). This will throw all sorts of exceptions, but these are properly caught.
public void DoInBackground(.........) {
try {
URL url = new URL(uri);
URLConnection conn = url.openConnection();
if (!failed) {
isr = new InputStreamReader(conn.getInputStream());
if (!failed) {
reader = new BufferedReader(isr);
publishProgress(1);
if (!failed) {
TagNode node = cleaner.clean(reader);
publishProgress(2);
return node;
}
}
}
} catch (Exception e) {
failed = true;
Log.v("error",""+e);
}
}
#Override
protected void onCancelled() {
failed = true;
if (reader != null)
try {
reader.close();
} catch (IOException e) {
failed = true;
}
if (isr != null)
try {
isr.close();
} catch (IOException e) {
}
}
I know that I could have broken up the downloading process in even tinier bits, but I am downloading very small files, so it's not that important.

problem loading image from web (android)

public Object fetch(String address) throws MalformedURLException,
IOException {
URL url = new URL(address);
Object content = url.getContent();
return content;
}
private Drawable ImageOperations(Context ctx, String url) {
try {
InputStream is = (InputStream) this.fetch(url);
Drawable d = Drawable.createFromStream(is, "src");
return d;
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
}
catch (Exception e)
{
return null;
}
}
try {
Drawable a =ImageOperations(this,"url"); imgView.setImageDrawable(a);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
This works, but on rare ocasions the app freezes due to a "SocketException: Adress family not supported by protocol". Is there any way to fix this? Thanks
You are trying to Download a File from the UI Thread...(which is why your UI Freezes)
Use a Seperate Thread or AsyncTask so that your UI doesn't Freeze up.
This should solve your problem.
As st0le has pointed out you are trying to do the heavy duty stuff from the UI thread.
All heavy-duty stuff in Android should be done on other worker thread. Because doing it in main thread (or the UI thread) can make your application unresponsive and may be killed as the system is persuaded to think that it has hung.
So you have to do the long running operations in separate thread. For implementing this you can use the concept of Handlers.

Categories

Resources