Why AsyncTask doesn't show result first time? - android

I have a text file on a server (right now on a local server by WAMP in c:/wamp/www/android/sample.txt ) and an android application with 3 activity that read data through the WiFi.
The first one get the address (on local host use 10.0.2.2/android/sample.txt) and go to activity2. In activity2 I have a button that goes to activity3.
code is third activity:
private InputStream OpenHttpConnection(String urlString) throws Exception {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection)) {
throw new IOException("NOT an HTTP Connection!");
}
try {
HttpURLConnection httpCon = (HttpURLConnection) conn;
httpCon.setAllowUserInteraction(false);
httpCon.setInstanceFollowRedirects(true);
httpCon.setRequestMethod("GET");
httpCon.connect();
response = httpCon.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpCon.getInputStream();
Log.d("myerr", response + "");
}
} catch (Exception e) {
Log.d("myerr2", e.getLocalizedMessage());
throw new IOException("Error Connection!");
}
return in;
}
private String DownloadText(String URL) {
int BUFFER_SIZE = 2000;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
} catch (Exception e) {
Log.d("myerr", e.getLocalizedMessage());
return "";
}
InputStreamReader isr = new InputStreamReader(in);
int charRead;
String str = "";
char[] inputBuffer = new char[BUFFER_SIZE];
try {
while ((charRead = isr.read(inputBuffer)) > 0) {
String readString = String
.copyValueOf(inputBuffer, 0, charRead);
str += readString;
inputBuffer = new char[BUFFER_SIZE];
}
in.close();
} catch (Exception e) {
Log.d("myerr", e.getLocalizedMessage());
return "";
}
return str;
}
private class DownloadTextTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
return DownloadText(urls[0]);
}
protected void onPostExecute(String result) {
Global.readedDataFromFile=result;
//Toast.makeText(DrawRhActivity.this,"Result: "+Global.readedDataFromFile, Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw_rh);
String user_address = Global.ip_address;
new DownloadTextTask().execute(user_address);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("Value: " + Global.readedDataFromFile);
}
I also define some global variable in Global.java .
AND HERE IS MY PROBLEM:
The 3rd activity doesn't show data on textview at the first time. but when I back to 2nd activity and hit the button my data loaded.
Why AsyncTask doesn't show result first time and how to fix this?
Thanks for your attention.

tv.setText("Value: " + Global.readedDataFromFile);
write this line in onPostExecute
protected void onPostExecute(String result) {
Global.readedDataFromFile=result;
//Toast.makeText(DrawRhActivity.this,"Result: "+Global.readedDataFromFile, Toast.LENGTH_LONG).show();
tv.setText("Value: " + Global.readedDataFromFile);
}

Solution:
put tv.setText("Value: " + Global.readedDataFromFile); in your onPostExecute method.
Explaination:
AsyncTask runs on separate thread instead of your UI thread.
so when it is being executed Global.readedDataFromFile may be empty.and when execution completes it goes in onPostExecute method and now Global.readedDataFromFile have some value stored in it.
Issue:
you are setting the text instantly after calling new DownloadTextTask().execute(user_address);
so it may happen that the AsyncTask is not completed yet and Global.readedDataFromFile is empty.
Reference:
AsyncTask
I hope it will be helpful !!

the problem lies within your onCreate function:
String user_address = Global.ip_address;
new DownloadTextTask().execute(user_address);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("Value: " + Global.readedDataFromFile);
First you start a task, then you want to set your views, but your task is not finished.
You have to set the views with the result of your task in to onPostExecute of the task.

Keep your DownloadTextTask &
Trying this code in your Activity
DownloadTextTask textTask = new DownloadTextTask();
textTask.execute(user_address);
String strDownloaded = "";
try {
strDownloaded = textTask.get();
} catch (Exception e) {
Log.e("DownloadTextTask", "Error: " + e.getMessage());
}

Related

Screen freezes when downloading content from server in android

I am downloading JSON Content from server in the MainActivity and passing the JSON from MainActivity to ListActivity, the problem here is I have added a sleep time of 10s in the backend server i.e. Php from where the data is fetched. Since, the response will the delayed I would expect that screen opens and waits until the response comes and move to next screen.
But what is happening is the screen goes white/black completely untill the response is recieved and ListActivity is loaded, the problem here is the MainActivity is never visible. Below is code for the same:
MainActivity
JSONData jsonData = new JSONData();
String jsonList = jsonData.fetchList();
Intent intent = new Intent(getApplicationContext(),ListActivity.class);
intent.putExtra("jsonList",jsonList);
startActivity(intent);
finish();
JSON Data class
public String fetchList() {
try {
String list = new DownloadJSONData().execute(listURL).get().toString();
return list;
} catch (Exception e) {
return "";
}
}
private class DownloadJSONData extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
you are using get() method which accquires the main thread or ui thread untill the async task is completed
you should avoid using get() and also can use progress dialog in onPreExecute for displaying progression on network call to user

HttpURLConnection crashes application

I want to receive and send data with a web server but the code does not work
What do I do for this code to work?
Note this code inside onCreate
try {
URL url = new URL("http://myweb.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream Stream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(Stream);
BufferedReader b = new BufferedReader(reader);
StringBuilder s = new StringBuilder();
String str ="";
while ((str = b.readLine())!=null) {
s.append(str);
}
String data = s.toString();
TextView myText = (TextView) findViewById(R.id.Text);
myText.setText(data);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Make sure that you do network-related tasks on a separate thread in Android. Also, check that you have the INTERNET permission set.
If you want to then update the UI from another thread, you have to use
runOnUiThread (new Runnable () {
public void run() {
//update ui in here
}
}
All your code runs in Main thread which should be always used for setting up the UI and to listen for UI events such as on click listeners.
Network calls are not allowed on this thread as they might take long time. Use AsyncTask API of android which is designed for running code in separate thread.
Create a class like one below for all GET request tasks.
public class DownloadTask extends AsyncTask<String, Void, Integer> {
private String TAG = "InDownloadTask";
private DownloadCallback callback;
private String data;
public DownloadTask(DownloadCallback cb){
callback = cb;
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
data = response.toString();
result = 1;
} else {
result = 0;
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
callback.onFinishDownload(data, integer);
}
}
Create a callback interface that we use for the above class.
public interface DownloadCallback {
public void onFinishDownload(String data, Integer result);
}
Now from your activity onCreate
String url = "http://myweb.com/";
new DownloadTask(new DownloadCallback() {
public void onFinishDownload(String data, Integer result) {
if(result == 1)
myText.setText(data);
else
myText.setText("Error");
}
}).execute(url);
If you have many network related operations, use a Network library such as Volley which will take care of this.

Can Java's FutureTask be an alternative to AsyncTask?

The docs say AsyncTask is designed to handle short operations(few seconds maximum) and states that Java classes like FutureTask are better for operations that last long. So I tried to send my location updates to the server using FutureTask but I am getting NetworkOnMainThreadException. I don't want to use AsyncTask because I wanted to keep the http connection open until the updates are cancelled. Here is my code:
SendLocation updates = new SendLocation(idt, String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
FutureTask ft = new FutureTask<String>(updates);
boolean b = ft.cancel(false);
ft.run();
class SendLocation implements Callable<String> {
String t, la, lo;
public SendLocation(String a, String b, String c){
this.t = a;
this.la = b;
this.lo = c;
}
public String call() {
sendUpdates(token, la, lo);
return "Task Done";
}
public void sendUpdates(String a, String b, String c){
HttpURLConnection urlConn = null;
try {
try {
URL url;
//HttpURLConnection urlConn;
url = new URL(remote + "driver.php");
urlConn = (HttpURLConnection) url.openConnection();
System.setProperty("http.keepAlive", "true");
//urlConn.setDoInput(true); //this is for get request
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json");
urlConn.setRequestMethod("POST");
urlConn.connect();
try {
//Create JSONObject here
JSONObject json = new JSONObject();
json.put("drt", a);
json.put("drlat", b);
json.put("drlon", c);
String postData = json.toString();
// Send POST output.
OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
os.write(postData);
Log.i("NOTIFICATION", "Data Sent");
os.flush();
os.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String msg = "";
String line = "";
while ((line = reader.readLine()) != null) {
msg += line;
}
Log.i("msg=", "" + msg);
} catch (JSONException jsonex) {
jsonex.printStackTrace();
Log.e("jsnExce", jsonex.toString());
}
} catch (MalformedURLException muex) {
// TODO Auto-generated catch block
muex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
try { //if there is IOException clean the connection and clear it for reuse(works if the stream is not too long)
int respCode = urlConn.getResponseCode();
InputStream es = urlConn.getErrorStream();
byte[] buffer = null;
int ret = 0;
// read the response body
while ((ret = es.read(buffer)) > 0) {
Log.e("streamingError", String.valueOf(respCode) + String.valueOf(ret));
}
// close the errorstream
es.close();
} catch(IOException ex) {
// deal with the exception
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ERROR", "There is error in this code " + String.valueOf(e));
}
}
}
Doesn't it get executed in a worker thread? If the answer is no why does the docs say that it is an alternative to AsyncTask?
Your code must not be in the void run() method. This is where the asynchronous code is ran.

Informationparsing from URL-Request not working / Didn't found TextView

i need your help. I want to send a URL Request, get response and create a JSON Object. My first try was totally wrong. Now I found a tutorial and made a new try.
My Activity looks like:
public class Patienten extends Activity {
//Beacon Elemente
private String UUID;
private String Major;
private String Minor;
private TextView output;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_patienten);
output = (TextView) findViewById(R.id.output);
UpdateBeaconInformation();
Button cmdHit = (Button) findViewById(R.id.cmd_hit);
cmdHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JSONTask().execute("//http://kusber-web.de/JsonTest.txt");
}
});
setTitle(Surname + ", " + FirstName);
// output.setText(output.getText().toString() + "Gefundener Patient:\n" + "Name: " + Surname + ", " + FirstName + "\nGeb.-Dat: " + Birthdate);
}
Then I created a new Java Class and built an asyncTask with it. But I can't access to the textview output in onPostExecute to update it.
public class JSONTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... urls) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
//http://kusber-web.de/JsonTest.txt
//http://nilsbenning.selfhost.me/PatientFinder.php?beacon_comID=5181f8a3-7354-46ac-b22d-952ec395ab06&beacon_major=12&beacon_minor=249
URL url = new URL(urls[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
output.setText(result);
}
}
What is my mistake? Why I can't access to it? I saw it as a solution here but didn't get it to work:
https://stackoverflow.com/a/12252717/5743912
Hope you can help me now! :)
You probably want to fix this (remove leading slashes):
new JSONTask().execute("//http://kusber-web.de/JsonTest.txt");
In your JSONTask you can reference members of Patienten by using Patienten.this. So in onPostExecute you should change this:
output.setText(result);
to:
Patienten.this.output.setText(result);

AsyncTask usage on Android

I use AsnycTask to connect URL and parse the return xml:
class Connecting extends AsyncTask<String, String, String> {
private String URLPath = "";
private HttpURLConnection Connection;
private InputStream InputStream;
private boolean Return1 = false;
private int Return2 = -1;
public Connecting (String fn, String u) {
FileName = fn;
URLPath = u;
Connection = null;
InputStream = null;
Return1 = false;
Return2 = -1;
execute();
}
public boolean getReturn1() {
return Return1;
}
public int getReturn2() {
return Return2;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
try {
URL url = new URL(URLPath);
Connection = (HttpURLConnection)url.openConnection();
Connection.setConnectTimeout(10000);
Connection.setReadTimeout(10000);
Connection.setDoInput(true);
Connection.setUseCaches(false);
Connection.connect();
InputStream = Connection.getInputStream();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String unused) {
super.onPostExecute(unused);
try {
InputStreamReader fsr = new InputStreamReader(InputStream);
BufferedReader br = new BufferedReader(fsr);
String line = "";
while((line = br.readLine()) != null) {
//parse Reture1 and Return2
}
}
catch(Exception e) {
e.printStackTrace();
}
Connection = null;
}
}
And I use below code to call it:
Connecting con = new Connecting(Name, URL);
System.out.println("Return1 " + con.getReturn1());
System.out.println("Return2 " + con.getReturn2());
It will get false and -1, which the init value.
And connect URL after print message.
I want to get the value which has connect success and parse from the xml.
How can I do it?
AsyncTask is a class that helps to run in background. You can use it if you want to access to remote server using for example HTTP connection.
In doBackground method you have to the the "heavy" task, the one that requires time and could block the UI. When you finish at the end of doBackground you have to return the value that is the result of the task.
Then in the onPostExecute you use this result to update for example the UI.
In your case it seems to me you aren't using correctly the AsyncTask. First of all you return null in doBackground and dont set return1 and return2 as you should.
And in onPostExecute you read the response while yuo should do it in doBackground.
There's another method you can override called onPreExecute that is called before doBackground method.
In my blog i've an example how to use AsyncBackground in this case and it could help you. If you like give a look here
The AsyncTask runs (as the name says) asynchronously to the main-thread.
If you want to happen something after the task is done, you have to put that code in the onPostExecute() method.
So you may put the System.out there.

Categories

Resources