AsyncTask and onPreExecute - java

When I run the AsyncTask below, I can see the log messages. However progress bar wont change visibility.
Below, is my AsyncTask code.
class test extends AsyncTask<String, Void, String> {
private Context mContext;
public PostWav(Context context) {
mContext = context;
}
protected String doInBackground(String... params ) {
URL url= null;
try {
url = new URL(params[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
InputStream inputStream;
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
JSONObject object = new JSONObject();
try {
object.put("provider_id",1);
String message = object.toString();
HttpPost httppost = new HttpPost(url.toString());
httppost.setEntity(new StringEntity(message, "UTF8"));
httppost.setHeader("Content-type", "application/json");
httppost.setHeader("Accept", "application/json");
String boundary = "-------------" + System.currentTimeMillis();
httppost.setHeader("Content-type", "multipart/form-data; boundary="+boundary);
File file = getDir("test", Context.MODE_PRIVATE);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
File wavFile = new File(file.getPath() + "/" + params[3]);
ContentType contentType = ContentType.create("audio/x-wav");
FileBody cbFile = new FileBody(wavFile,contentType,"sample");
builder.addPart("sample", cbFile);
builder.setBoundary(boundary);
httppost.setEntity(builder.build());
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
Header[] header = response.getHeaders("Location");
String location = String.valueOf(header[0].getValue());
inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
return location;
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
Log.i("Async-Example", "onPreExecute Called");
loading.setVisibility(View.VISIBLE);
record.setVisibility(View.INVISIBLE);
super.onPreExecute();
}
#Override
protected void onPostExecute(String feed) {
Log.i("Async-Example", "onPostExecute Called");
loading.setVisibility(View.INVISIBLE);
record.setVisibility(View.VISIBLE);
}
}
I am uploading a .wav file to a my API. I did not included whole code this is basically all that I'm doing.

#greenapps Thanks mate your hint was more than enough for me to understand the problem.
Basically when I imported this class from another project I completely forgot the reason she was programmed like that.
I just had to remove .get() from the execute command and passed the methods to the post execute on the Task and everything when smoothly.
I am sorry for taking everyone's time, I really appreciated the help!
Here is the result i was looking for:

You would like to show the progress bar while the task is being completed, so you need to work around this statement.
Try to do the work in the following method(s):
doInBackground(int Progress)
OnProgressUpdate() to update the progress bar according to your ideas
For more read the following documentation.

Normally AsyncTask runs on the UI Thread, but I have the strong assumption that you are calling this from somewhere else than the UI Thread since you are passing the Context as a Parameter.
So you can use that.
#Override
protected void onPostExecute(String feed) {
Log.i("Async-Example", "onPostExecute Called");
activity.runOnUiThread(new Runnable(){
loading.setVisibility(View.INVISIBLE);
record.setVisibility(View.VISIBLE);
});
}
Also remove super.onPreExecute(); you dont need that
You have to change your constructor parameter from Context to Activity or it will be a bit more complicated.

Related

Getting text from an url with AsyncTask. Code is not working for some reason

I am trying to get text from urls and display them as strings. Urls end with .txt as in www.gains.com/more.txt These text are long and they have a maximum size of 1MB. I am trying to get them it with AsyncTask. The problem is that the code sometimes works and sometimes doesn't. I have no idea why.
Here is the AsyncTask code.
class RequestTask extends AsyncTask<String, String, String>{
#Override
// username, password, message, mobile
protected String doInBackground(String... url) {
// constants
int timeoutSocket = 15000; //Is this enough for 1MB files?
int timeoutConnection = 15000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient client = new DefaultHttpClient(httpParameters);
HttpGet httpget = new HttpGet(url[0]);
try {
HttpResponse getResponse = client.execute(httpget);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if(statusCode != HttpStatus.SC_OK) {
Log.w("MyApp", "Download Error: " + statusCode + "| for URL: " + url);
return null;
}
line = "";
StringBuilder total = new StringBuilder();
HttpEntity getResponseEntity = getResponse.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(getResponseEntity.getContent()));
while((line = reader.readLine()) != null) {
total.append(line);
}
line = total.toString();
return line;
} catch (Exception e) {
Log.w("MyApp", "Download Exception : " + e.toString());
}
return null;
}
#Override
protected void onPostExecute(String result) {
story.add(result); //story is the array which I use to display the downloaded text
}
}
And here is how i call it. I call it inside a method which is not OnCreate and I even do it inside a new thread to avoid the NetworkOnMainThreadException error.
new Thread() {
#Override
public void run() {
new RequestTask().doInBackground("www.gains.com/more.txt");
new RequestTask().onPostExecute(line);
}
}.start();
it's not the right way to call asynctask. You can t call doinbackground direclty, neither postexecute.
What you have to do is just to write :
RequestTask MyAsynchTask = new RequestTask().
MyAsynchTask.execute("www.gains.com/more.txt");
it s the public execute method who will call all the method for you : preexecute, doinbackground and postexecute.
and you won t have ANR problem ( Application Not Responding ) with this solution.
tell me if it's ok for you
you said : sometimes it works sometimes no ? when you write :
requestTask().doInBackground("www.gains.com/more.txt");
new RequestTask().onPostExecute(line);
java can t' know in postexecute if doinbackground is finished or not ! so sometimes you will have your result, and sometimes no, it depends of how much time java takes to work in the doinbackgroundmethod.
the only way to implement Asynchtask is to do as i write above. And if you havent the data you wish to have in the result it because of something else.
IT CAN RUN JUST ONCE : if you want to run it again you have to create antother instance of RequestTask
Instead of the following code :
new Thread() {
#Override
public void run() {
new RequestTask().doInBackground("www.gains.com/more.txt");
new RequestTask().onPostExecute(line);
}
}.start();
Use just :
new RequestTask().execute("www.gains.com/more.txt");

Perform AsyncTask on Android / Posting JSON

I am working on an android app, and am running into some troubles with registering users. I want to post a JSON object to my server and receive one back. I can successfully create a JSON object with the right information but when I go to post it I get a NetworkOnMainThreadException or my HttpClient class returns null when it should be returning a JSONObject and I am very confident that my web server works correctly. I understand that you cannot connect to the network on the main thread and have created an HttpClient class that uses AsnycTask (although probably not correctly). I have been working on this for quite a while and would appreciate any guidance in the right direction.
//Main activity
#Override
public void onClick(View arg0) {
if(!(isEmpty(name) || isEmpty(username) || isEmpty(password) || isEmpty(email))) {
user = new JSONObject();
try {
user.put("username", username.getText().toString());
user.put("name", name.getText().toString());
user.put("email", email.getText().toString());
user.put("password", password.getText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
jRegister = new JSONObject();
try {
jRegister.put("apiToken", Utilities.apiToken);
jRegister.put("user", user);
Log.i("MainActivity", jRegister.toString(2));
} catch (JSONException e) {
e.printStackTrace();
}
//
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
HttpClient Class
public class HttpClient extends AsyncTask<Void, Void, JSONObject>{
private final String TAG = "HttpClient";
private String URL;
private JSONObject jsonObjSend;
private JSONObject result = null;
public HttpClient(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
#Override
protected JSONObject doInBackground(Void... params) {
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
JSONObject jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
return jsonObjRecv;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject jObject) {
result = jObject;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
I understand that you cannot connect to the network on the main thread
and have created an HttpClient class that uses AsnycTask (although
probably not correctly).
You are right you have not implemented it the right way.
In your onClick events (still on Main thread) you performed a network activity causing the error:
HttpClient client = new HttpClient(url, jRegister);
result = client.getJSONFromUrl();
Instead you should run the network operation inside of the AsnycTask
public class GetJsonTask extends AsyncTask<Void, Void, JSONObject >{
private String URL;
private JSONObject jsonObjSend;
public GetJsonTask(String URL, JSONObject jsonObjSend) {
this.URL = URL;
this.jsonObjSend = jsonObjSend;
}
#Override
protected JSONObject doInBackground(Void... params) {
JSONObject jsonObjRecv;
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpPostRequest = new HttpPost(URL);
StringEntity se;
se = new StringEntity(jsonObjSend.toString());
// Set HTTP parameters
httpPostRequest.setEntity(se);
httpPostRequest.setHeader("Accept", "application/json");
httpPostRequest.setHeader("Content-type", "application/json");
long t = System.currentTimeMillis();
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-t) + "ms]");
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
// convert content stream to a String
String resultString= convertStreamToString(instream);
instream.close();
resultString = resultString.substring(1,resultString.length()-1); // remove wrapping "[" and "]"
jsonObjRecv = new JSONObject(resultString);
// Raw DEBUG output of our received JSON object:
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
}
}
catch (Exception e) {
e.printStackTrace();
}
return jsonObjRecv;
}
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}else {
tv.setText("");
}
}
}
Then you call your async in onclik method like this:
public void onClick(View arg0) {
//.......
GetJsonTask client = new GetJsonTask(url, jRegister);
client.execute();
}
One problem in your code is that your expectations of AsyncTask aren't quite right. In particular this function:
public JSONObject getJSONFromUrl() {
this.execute();
return result;
}
AsyncTask runs the code in the doInBackground() function in a separate thread. This means that once you call execute() you have two parallel lines of execution. You end up with what's called a Race Condition. When you reach the return result line, a couple of things can be happening:
doInBackground() hasn't run and therefore result is still has the default value. In this case null.
doInBackground() can be in the middle of the code. In your particular case because it doesn't modify result then this doesn't affect you much. But it could be on any line (or middle of a line sometimes if operations aren't atomic) when that return happens.
doInBackground() could've finished, but since onPostExecute() runs on the UI thread it has to wait until your onClick handler is finished. By the time onPostExecute() has a chance to run onClick already tried to update tv with whatever it was that getJSONFromUrl returned, most likely null.
The way to set up tasks with AsyncTask is to give it the information it needs to do it's work, start it up with execute, and since you can't know how long it will take to complete, let it handle the finishing steps of the task.
This means that after calling execute you don't wait around for it's result to update views (like in your case), but rather rely on the AsyncTask's onPostExecute or related methods to take over the next steps.
For your case this would mean that your onPostExecute should look something like:
protected void onPostExecute(JSONObject result) {
try {
if(result != null)
tv.setText(result.toString(2));
else
tv.setText("null");
} catch (JSONException e) {
e.printStackTrace();
}
}

What is the most efficient way on Android to call HTTP Web API calls that return a JSON response?

I'm the perfectionist type, I already got web API calls working fine with Google Places API (just as an example), but I feel it's sometimes slow or maybe I'm not doing it right. Some blogs are saying I should use AndroidHttpClient, but I'm not, should I ?
The web API calls i'm using return json and I don't run them on the UI thread, hence using AsyncTask (is AsyncTask the most efficient way to run on background thread or should I use something else ?)
Please see my code and tell me how could it be more efficient in anyway
public static class NearbySearchRequest extends AsyncTask<String, Void, JSONObject>
{
Exception mException = null;
#Override
protected void onPreExecute()
{
super.onPreExecute();
this.mException = null;
}
#Override
protected JSONObject doInBackground(String... params)
{
StringBuilder urlString = new StringBuilder();
urlString.append("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
urlString.append("key=").append(Constants.GOOGLE_SIMPLE_API_KEY);
urlString.append("&location=").append(params[0]);
urlString.append("&sensor=").append("true");
urlString.append("&language=").append("en-GB");
urlString.append("&name=").append(params[1]);
urlString.append("&rankby=").append("distance");
LogHelper.Log(urlString.toString());
HttpURLConnection urlConnection = null;
URL url = null;
JSONObject object = null;
try
{
url = new URL(urlString.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
InputStream inStream = null;
inStream = urlConnection.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
String temp, response = "";
while ((temp = bReader.readLine()) != null)
response += temp;
bReader.close();
inStream.close();
urlConnection.disconnect();
object = (JSONObject) new JSONTokener(response).nextValue();
}
catch (Exception e)
{
this.mException = e;
}
return (object);
}
#Override
protected void onPostExecute(JSONObject result)
{
super.onPostExecute(result);
if (this.mException != null)
ErrorHelper.report(this.mException, "Error # NearbySearchRequest");
}
}
The Http engine you're using seems the best choice. Actually any other 3-rd party engines are based either on Apache, either on HttpUrlConnection. I prefer to use Spring for Android as that API provide an abstraction over Http Engine and you don't really need to care how about what API to use based on API level. Or you can use Volley - a very fashionable library.
I would touch however some of your code:
What if there is an exception while reading the stream? Then the stream remains open and also the connection. So I would suggest to have a finally block where the streams and connection is closed no matter if you get an exception or not:
HttpURLConnection urlConnection = null;
URL url = null;
JSONObject object = null;
InputStream inStream = null;
try {
url = new URL(urlString.toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
inStream = urlConnection.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
String temp, response = "";
while ((temp = bReader.readLine()) != null) {
response += temp;
}
object = (JSONObject) new JSONTokener(response).nextValue();
} catch (Exception e) {
this.mException = e;
} finally {
if (inStream != null) {
try {
// this will close the bReader as well
inStream.close();
} catch (IOException ignored) {
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
JSON parsing: you're using the Android standard way of parsing JSON, but that's not the fastest and easiest to work with. GSON and Jackson are better to use. To make a comparison when it comes for JSON parsers, I would go for Jackson. Here's another SO topic on this comparison.
Don't concatenate strings like that as concatenating strings will create each time another string. Use a StringBuilder instead.
Exception handling (this is anyway a long-debate subject in all programming forums). First of all you have to log it (Use Log class not System.out.printXXX). Then you need to either inform the user: either you toast a message, either you show a label or notification. The decision depends on the user case and how relevant is the call you're making.
These are the topics I see in you code.
EDIT I realize I didn't answer this: is AsyncTask the most efficient way to run on background thread or should I use something else?
The short answer I would give is: if you're supposed to perform a short time lived request, then AsyncTask is perfect. However, if you need to get some data and display it - but you don't want to worry about whether to download again if the screen is rotated and so on, I would strongly recommend using an AsyncTaskLoader and Loaders in general.
If you need to download some big data, then either you use an IntentService or, for heavy-weight operations, DownloadManager.
Enjoy coding!
------Create a Service Handler Class to your Project--------
public class ServiceHandler {
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/*
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
Log.e("in POST","in POST");
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
Log.e("in POST params","in POST params");
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
Log.e("url in post service",url);
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
Log.e("in GET","in GET");
if (params != null) {
Log.e("in GET params","in GET params");
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
Log.e("url in get service",url);
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
public String makeServiceCallIMAGE(String url, int method,
List<NameValuePair> params) {
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
--------------AsyncTask For Login------------------
public class Login_Activity extends ActionBarActivity {
//Internet Service
NetworkConnection nw;
ProgressDialog prgDialog;
Boolean netConnection = false;
//
//Login API
String loginURL ="url";
//
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
nw = new NetworkConnection(getApplicationContext());
prgDialog = new ProgressDialog(this);
// Set Cancelable as False
prgDialog.setCancelable(false);
new LoginOperation().execute();
}
private class LoginOperation extends AsyncTask<String, Void, Void> {
String status, message;
#Override
protected void onPreExecute() {
// Set Progress Dialog Text
prgDialog.setMessage("Logging...");
prgDialog.show();
}
#Override
protected Void doInBackground(String... urls) {
if(nw.isConnectingToInternet() == true)
{
try
{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("method", "ClientesLogin"));
nameValuePairs.add(new BasicNameValuePair("Email", str_Email));
nameValuePairs.add(new BasicNameValuePair("Senha", str_Password));
ServiceHandler sh = new ServiceHandler();
String response = sh.makeServiceCall(loginURL, ServiceHandler.GET,
nameValuePairs);
Log.e("response", response);
JSONObject js = new JSONObject(response);
status = js.getString("status");
Log.e("status",status);
if(status.contains("Fail"))
{
message = js.getString("message");
}
/*else
{
JSONObject jslogin=js.getJSONObject("user_list");
for (int i = 0; i < jslogin.length(); i++) {
}
}*/
}catch(Exception ex){
}
netConnection = true;
}else
{
netConnection = false;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
prgDialog.dismiss();
if(netConnection == false)
{
Toast toast = Toast.makeText(getApplicationContext(),"Internet is not available. Please turn on and try again.", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
else
{
if(status.contains("Success"))
{
Toast toast = Toast.makeText(getApplicationContext(), "Login Successful", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
Intent i=new Intent(Login_Activity.this,home_page_activity.class);
startActivity(i);
}
else{
Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
super.onPostExecute(result);
}
}
}
---------------Network Connection class---------------------
public class NetworkConnection {
Context context;
public NetworkConnection(Context context){
this.context = context;
}
public boolean isConnectingToInternet(){
ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED)
{
return true;
}
}
return false;
}
}
JSONArray main1 = js.getJSONArray("Test 1");
for (int i = 0; i < main1.length(); i++) {
JSONObject jsonObject = main1.getJSONObject(i);

reading JSON data from URL

I am trying to parse some JSON data, but my app doesn't do anything because i can't seem to get any response from URL, i tried to open URL connection in few different ways, but it's still the same. for Example :
urlMy=new URL(string);
URLConnection tc = urlMy.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
String line=in.readLine();
doesn't return anything, it even dismisses everything in my function written below that code.
Or
urlMy=new URL(examp);
InputStream inputStream = urlMy.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bR = new BufferedReader(reader);
the same thing. This function is called and like it never happend, every function after this one executes, so it's not in the endless loop, but every bit of code in this function after this example code is ignored. if i remove this code for reading url, everthing else works.
Try to use AsyncTask,try something like:
class MyAsyncTask extends AsyncTask<String, String, Void> {
private ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
InputStream inputStream = null;
String result = "";
protected void onPreExecute() {
progressDialog.setMessage("Downloading your data...");
progressDialog.show();
progressDialog.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface arg0) {
MyAsyncTask.this.cancel(true);
}
});
}
#Override
protected Void doInBackground(String... params) {
String url_select = "http://yoururlhere.com"
ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
try {
// Set up HTTP post
// HttpClient is more then less deprecated. Need to change to URLConnection
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
// Read content & Log
inputStream = httpEntity.getContent();
} catch (UnsupportedEncodingException e1) {
Log.e("UnsupportedEncodingException", e1.toString());
e1.printStackTrace();
} catch (ClientProtocolException e2) {
Log.e("ClientProtocolException", e2.toString());
e2.printStackTrace();
} catch (IllegalStateException e3) {
Log.e("IllegalStateException", e3.toString());
e3.printStackTrace();
} catch (IOException e4) {
Log.e("IOException", e4.toString());
e4.printStackTrace();
}
// Convert response to string using String Builder
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Log.e("StringBuilding & BufferedReader", "Error converting result " + e.toString());
}
} // protected Void doInBackground(String... params)
protected void onPostExecute(Void v) {
//parse JSON data
try{
JSONArray jArray = new JSONArray(result);
for(i=0; i < jArray.length(); i++) {
JSONObject jObject = jArray.getJSONObject(i);
String name = jObject.getString("name");
String tab1_text = jObject.getString("tab1_text");
int active = jObject.getInt("active");
} // End Loop
this.progressDialog.dismiss();
} catch (JSONException e) {
Log.e("JSONException", "Error: " + e.toString());
} // catch (JSONException e)
} // protected void onPostExecute(Void v)
} //class MyAsyncTask extends AsyncTask<String, String, Void>
In the last Google I/O, Google released a new library called Volley. It's fast for HTTP requests, very easy to use and you can set it up to return JSONObjects ready for parsing. https://developers.google.com/events/io/sessions/325304728

android use asynctask to parse json

I am working on android application and I need to parse my json object with data. How you can see I create JSONParser class and try to use asynctask but there is something wrong and I can't understand where is the problem. Every time I use it resultJSON is null. Hope that you can give me an advice!
public class JSONParser {
private String resultJSON;
public JSONArray getJSON(String url) throws JSONException {
Parser parser = new Parser();
parser.execute(url);
return json;
}
private class Parser extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
for (String url : urls) {
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
resultJSON = builder.toString();
} else {
Log.e(JSONParser.class.toString(), "Failed to download file");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultJSON;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
json = new JSONArray(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Why don't you JSONArray json = new JSONArray(resultJSON); do this on post execute method of async task .
And i will not suggest varevarao way , as it will create extra burden of one thread .
You should use the get() method of the AsyncTask class to retrieve the result of the task. It waits for the task to complete and gets the result (which means it'd be best if you enclose it within a separate thread with a progress dialog or just a background thread).
public JSONArray getJSON(String url) throws JSONException {
Parser parser = new Parser();
parser.execute(url);
resultJSON = parser.get(); // Probably put this in a Thread to avoid spending too much time waiting for a result on the main thread
JSONArray json = new JSONArray(resultJSON);
return json;
}
The problem is fixed. It's an awful workaround but it works. Add this line
while(json==null) {}
after calling the execute method.

Categories