I googled for hours and tried all answers of Stack Overflow but didn't solved my problem.
I made android program to download data in bytes which wroks perfectly. And for download working on background thread. I want to show a Progress Dialog(jus Spinning one). But I'm having really annoying problem. My download takes about 5 sec but my progress dialog is either not shown or just shown for last 1 sec.
Here's my code for AsyncTask.
public class ImageJSON extends AsyncTask<String, String, byte[]> {
private JSONObject jsonObject = new JSONObject();
private byte[] response;
private ProgressDialog pg;
private Context context;
public ImageJSON(Activity activity) {
pg = new ProgressDialog(activity);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pg.setMessage("Downloading, please wait.");
pg.show();
}
#Override
protected void onProgressUpdate(String... progress) {
super.onProgressUpdate(progress);
if (pg != null) {
pg.setProgress(Integer.parseInt(progress[0]));
}
}
protected void onPostExecute(byte[] result) {
if (pg.isShowing()) {
pg.dismiss();
}
}
#Override
protected byte[] doInBackground(String... params) {
HttpPost httpPost = new HttpPost("my file url....");
HttpClient httpClient = new DefaultHttpClient();
HttpContext httpContext = new BasicHttpContext();
try {
jsonObject.put("imageId", params[0]);
StringEntity stringEntity = new StringEntity(jsonObject.toString());
httpPost.addHeader("Content_Type", "application/octet_stream");
httpPost.setEntity(stringEntity);
HttpResponse httpResponse = httpClient.execute(httpPost, httpContext);
HttpEntity entity = httpResponse.getEntity();
if (entity!=null) {
response = EntityUtils.toByteArray(entity);
entity.consumeContent();
httpClient.getConnectionManager().shutdown();
}
} catch (JSONException|IOException e) {
e.printStackTrace();
}
return response;
}
And I called it from my activity using this code.
final ImageJSON imageTask = new ImageJSON(ReaderActivity.this);
byte[] response = imageTask.execute(imageId).get();
If anybody can help me, Thanks in advance.
You don't want to be using get() as it still freezes your UI thread thus denying the sense of using AsyncTask. You might want to implement onPostExecute in order to return your result properly.
try this -
public ImageJSON(Activity activity) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pg = new ProgressDialog(ReaderActivity.this);
pg.setMessage("Downloading, please wait.");
pg.show();
}
you forgot to initilise your progressDialogue in onPreExecute method
#Override
protected void onPreExecute() {
super.onPreExecute();
pg = new ProgressDialog(pass_context_here);
pg.setMessage("Downloading, please wait.");
pg.show();
}
Change this
public ImageJSON(Context ctx) {
this.context = ctx;
}
Now in your onPreExecute() method use this
#Override
protected void onPreExecute() {
super.onPreExecute();
pg = new ProgressDialog(context);
pg.setMessage("Downloading, please wait.");
pg.show();
}
You'r initializing your ProgressDialog in ImageJSON class which block your UI thread means freezes it. So need to initialize it in onPreExecute() method with reference of context.
Related
I am trying to create a dialog when loading Httprequest. But it load during the i click to intent from last Activity, but not the start of this Activity.
And the dialog just shown in 0.00001sec then dismiss.
Am i implement it wrongly?
Here is my codes
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HttpPostHandler2 handler = new HttpPostHandler2();
String URL ="http://xxxxxx";
handler.execute(URL);
}
public class HttpPostHandler2 extends AsyncTask<String, Void, String> {
private String resultJSONString = null;
private ProgressDialog pDialog;
public String getResultJSONString() {
return resultJSONString;
}
public void setResultJSONString(String resultJSONString) {
this.resultJSONString = resultJSONString;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please Wait");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST,
AuthScope.ANY_PORT), new UsernamePasswordCredentials("core",
"core1234"));
String responseContent = "";
HttpClient httpClient = new DefaultHttpClient();
((AbstractHttpClient) httpClient).setCredentialsProvider(credProvider);
HttpPost httpPost = new HttpPost(params[0]);
HttpResponse response = null;
try {
// Execute HTTP Post Request
response = httpClient.execute(httpPost);
responseContent = EntityUtils.toString(response.getEntity());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
setResultJSONString(responseContent);
// return new JSONObject(responseContent);
return responseContent;
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
super.onPostExecute(result);
resultJSONString = result;
}
}
Make sure that the work of HttpPostHandler2 is long enough to display the pDialog. If it not, it will disappear really soon.
However, you cannot display GUI in onCreate. To display the dialog, you should move them to onStart:
#Override
public void onCreate(Bundle savedInstanceState) {//GUI not ready: nothing is shown
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HttpPostHandler2 handler = new HttpPostHandler2();
}
#Override
protected void onStart () {//GUI is ready
String URL ="http://xxxxxx";
handler.execute(URL);
}
See comment for more information.
Im new to Android Development. I want to fill spinner by Json array which load from the Http request(by AsyncTask). My AsyncTask in seperate class called Load_spinnrs. I to do this?
here is my http request
try{
String DataSendingTo="http://www.mysite.com/AppRequest/load_data";
//HttpClient
HttpClient httpClient = new DefaultHttpClient();
//Post header
HttpPost httpPost = new HttpPost(DataSendingTo);
//Adding data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("authorized","001"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
JSONTokener tokener = new JSONTokener(builder.toString());
JSONArray finalResult = new JSONArray(tokener);
//How to load Spinner ?????
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
After you get array of JSON
You have to do like:
final String[] items = new String[jsonArray.length()];
// looping through All Contacts
for(int i = 0; i < jsonArray.length(); i++){
JSONObject c = jsonArray.getJSONObject(i);
// Storing each json item in variable
String name = c.getString(TAG_NAME);
items[i]=c.getString(TAG_NAME);
System.out.println("Hello events "+items);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adapter);
Populate an Android Spinner with JSON data from a RESTful web API
If you are extending AsyncTask in separate class then you will need to pass Activity context from which you are executing extending for accessing UI elements in on normal java class. for this you can use Load_spinnrs class constructor to get Activity context and use onPostExecute for accessing Spinner as:
class Load_spinnrs extends AsyncTask<String,String,String>{
Activity activity;
Context context;
public Load_spinnrs(Activity activity,Context context){
this.activity=activity;
this.context=context;
}
...
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
//access UI elements here..
Spinner mySpinner = (Spinner)activity.findViewById(R.id.my_spinner);
adapter = new ArrayAdapter<String> (context,
android.R.layout.simple_spinner_item, items);
//....
super.onPostExecute(result);
}
}
For pass Context start AsyncTask as from Activity:
Load_spinnrs load_spin=new Load_spinnrs(this,this);
load_spin.execute(parameters);
for easily understand, Load your Load_spinnrs class as, sub class of your main class.
for example;
public class Main_Class extends Activity
{
private Spinner spinner;
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.userprofiles);
//init spinner here
}
private class Load_spinnrs extends AsyncTask<Void, Void, String>{
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(Void... params) {
// your http request
}
#Override
protected void onPostExecute(String result) {
//update spinner here.
}
}
Here is the implementation in the AsyncTask to show the loading spinner and then dismiss it when the AsyncTask is complete.
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
<put code here>
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
}
}
Look at this may be help you:
GetServerData.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Server Request URL
String serverURL = "http://androidexample.com/media/webservice/getPage.php";
// Create Object and call AsyncTask execute Method
new LongOperation().execute(serverURL);
}
});
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//UI Element
uiUpdate.setText("Output : ");
Dialog.setMessage("Downloading source..");
Dialog.show();
}
for more details you have :
http://androidexample.com/AsyncroTask_Example_To_Get_Server_Data_-_Android_Example/index.php?view=article_discription&aid=59&aaid=84
http://www.androidhive.info/2013/12/android-populating-spinner-data-from-mysql-database/
Best regards
Can someone tell me, why progressbar isnt showing when picture is being uploaded. I copied asynctask structure from my old project where it works. In my old project i use asynctask to download pictures from web server, and to show progressbar while downloading.
Here is my code:
public class PreviewPostActivity extends Activity {
ImageView imageView;
TextView tvComment;
Button submit;
MyLocationListener locationListener;
List<NameValuePair> list = new ArrayList<NameValuePair>();
private final String url = "***"; //Url of php script
ProgressDialog pDialog;
String responseMessage="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preview_post);
Intent intent = this.getIntent();
imageView = (ImageView)findViewById(R.id.imgPerview);
tvComment = (TextView)findViewById(R.id.txtPreviewComment);
submit = (Button)findViewById(R.id.btnPreviewSubmit);
Bitmap image = (Bitmap)intent.getParcelableExtra("picture");
String comment = intent.getStringExtra("comment");
locationListener = (MyLocationListener)intent.getSerializableExtra("location");
String imagePath = intent.getStringExtra("imagePath");
String date = intent.getStringExtra("date");
imageView.setImageBitmap(image);
tvComment.setText(comment);
//tvComment.append("\n"+locationListener.latitude + "\n"+locationListener.longitude);
list.add(new BasicNameValuePair("image", imagePath));
list.add(new BasicNameValuePair("comment", comment));
list.add(new BasicNameValuePair("longitude", Double.toString(locationListener.longitude)));
list.add(new BasicNameValuePair("latitude", Double.toString(locationListener.latitude)));
list.add(new BasicNameValuePair("date", date));
submit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new uploadPost().execute();
}
});
}
public void post(List<NameValuePair> nameValuePairs) {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 100000);
HttpConnectionParams.setSoTimeout(httpParameters, 200000);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
try {
MultipartEntity entity = new MultipartEntity();
for(int index=0; index < nameValuePairs.size(); index++) {
if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) {
// If the key equals to "image", we use FileBody to transfer the data
entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File(nameValuePairs.get(index).getValue()),"image/jpeg"));
} else {
// Normal string data
entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
}
}
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
HttpEntity httpEntity = response.getEntity();
String responseMessage = EntityUtils.toString(httpEntity);
tvComment.setText(responseMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
class uploadPost extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(PreviewPostActivity.this);
pDialog.setMessage("Uploading post. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
//post(list);
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 100000);
HttpConnectionParams.setSoTimeout(httpParameters, 200000);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
try {
MultipartEntity entity = new MultipartEntity();
for(int index=0; index < list.size(); index++) {
if(list.get(index).getName().equalsIgnoreCase("image")) {
// If the key equals to "image", we use FileBody to transfer the data
entity.addPart(list.get(index).getName(), new FileBody(new File(list.get(index).getValue()),"image/jpeg"));
} else {
// Normal string data
entity.addPart(list.get(index).getName(), new StringBody(list.get(index).getValue()));
}
}
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
HttpEntity httpEntity = response.getEntity();
responseMessage = EntityUtils.toString(httpEntity);
//tvComment.setText(responseMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
});
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
tvComment.setText(responseMessage);
pDialog.dismiss();
}
}
So when i hit button for upload, screen freezes and stay frozen until upload is complete, and progress bar isnt showing at all. Sometimes it shows, but its rly rear and i dont know why. I have tried calling Post() method from class in doInBackground body insted of whole code (code in body is the same as in post() method) but effect is the same, so i guess i didnt do something right in creating progressbar. But again i say i copied whole asynctask code from old project in witch it worked fine.
EDIT:
I just tryed creating progress bar in constructor of PreviewPostActivity.class and after that i made constructor for asynctask class but it still dosent work. I am rly confused becouse it worked in my old program.
Here is code from him:
class GetSlike extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(KlubSlikeActivity.this);
pDialog.setMessage("Ucitavanje u toku. Molimo vas sacekajte...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
String id = Integer.toString(k.getId());
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("klub",id));
slikeUrl = JSONAdapter.getSlike(params);
gv.setAdapter(new SlikeAdapter(slikeUrl,KlubSlikeActivity.this));
}
});
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
Only thing changed is doInBackground body...
Edited:
Dialog is display after runOnUiThread() is executed.
I found this library which is perfect to accomplish the upload task and also provide a progress handler which could be used to set the value of a ProgressBar:
https://github.com/nadam/android-async-http
It could be used like the following... Set onClickHandler for the upload Button:
#Override
public void onClick(View arg0) {
try {
String url = Uri.parse("YOUR UPLOAD URL GOES HERE")
.buildUpon()
.appendQueryParameter("SOME PARAMETER IF NEEDED 01", "VALUE 01")
.appendQueryParameter("SOME PARAMETER IF NEEDED 02", "VALUE 02")
.build().toString();
AsyncHttpResponseHandler httpResponseHandler = createHTTPResponseHandler();
RequestParams params = new RequestParams();
// this path could be retrieved from library or camera
String imageFilePath = "/storage/sdcard/DCIM/Camera/IMG.jpg";
params.put("data", new File(imageFilePath));
AsyncHttpClient client = new AsyncHttpClient();
client.post(url, params, httpResponseHandler);
} catch (IOException e) {
e.printStackTrace();
}
}
then add this method to your activity code:
public AsyncHttpResponseHandler createHTTPResponseHandler() {
AsyncHttpResponseHandler handler = new AsyncHttpResponseHandler() {
#Override
public void onStart() {
super.onStart();
}
#Override
public void onProgress(int position, int length) {
super.onProgress(position, length);
progressBar.setProgress(position);
progressBar.setMax(length);
}
#Override
public void onSuccess(String content) {
super.onSuccess(content);
}
#Override
public void onFailure(Throwable error, String content) {
super.onFailure(error, content);
}
#Override
public void onFinish() {
super.onFinish();
}
};
return handler;
}
Run on ui thread in asynctask doinbackground() is not correct. Also you are returning null in doInBackground() and you have parameter file_url in onPostExecute(). Return value in doInbackground() recieve value in onPostExecute().
doInBackGround() runs in background so you cannot access or update ui here.
To update ui you can use onPostExecute().
Your AsyncTask should be something like below. You are doing it the wrong way.
http://developer.android.com/reference/android/os/AsyncTask.html. See the topic under The 4 steps
pd= new ProgressDialog(this);
pd.setTitle("Posting data");
new PostTask().execute();
private class PostTask extends AsyncTask<VOid, Void, Void> {
protected void onPreExecute()
{//display dialog.
pd.show();
}
protected SoapObject doInBackground(Void... params) {
// TODO Auto-generated method stub
//post request. do not update ui here. runs in background
return null;
}
protected void onPostExecute(Void param)
{
pd.dismiss();
//update ui here
}
public static class TestTask extends AsyncTask<Void, Integer, Integer> {
private String stacktrace;
public TestTask (String stacktrace){
this.stacktrace = stacktrace;
}
#Override
protected Integer doInBackground(Void... params) {
try {
Log.i("async", "doInBackground 1"); //this gets logged
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xx.xx:8080/android/service.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("action", "logexception"));
nameValuePairs.add(new BasicNameValuePair("stacktrace", stacktrace));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Log.i("async", "doInBackground 2"); //this gets logged
return 1;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
protected void onPreExecute(){
Log.i("async", "onPreExecute"); //this gets logged
}
#Override
protected void onPostExecute(Integer result) {
Log.i("async", "onPostExecute"); //this doenst get logged!
}
}
I've been checking out the other SO threads regarding this, but according to them, my code looks correct as far as i can tell. So why do i never reach Log.i("async", "onPostExecute");? Thanks
Did you create your AsyncTask on UI Thread?
Others seems good. Generics and annotations are fine.
So probably problem is that your doInBackground method never returns because onPostExecute is automatic called when doInBackground something will return.
You have to call the super in onPostExecute()
So you code should be like this:
#Override
public void onPostExecute(Integer result) {
super.onPostExecute(result);
Log.i("async", "onPostExecute");
}
And this should work
I try use below code to load an URL.
URL url = new URL(urlstr);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(10000);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
InputStream is = connection.getInputStream(); //spend lots of time
Because the line InputStream is = connection.getInputStream(); will spend some time.
So I want to show a loading dialog while it loading.
I can I do it?
In AActivity, below code to call BActivity.
Intent intent = new Intent(AActivity.this, BActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window w = MyGroup.group.getLocalActivityManager().startActivity("BActivity", intent);
View view = w.getDecorView();
MyGroup.group.setContentView(view);
And BActivity is load URL and extract information.
The load code is in onCreate().
I try the answer code, the error Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord#2afe9488 is not valid; is your activity running? shows.
You can achieve with the aysntask showing progress dialog as follows
In Oncreate :
new GetTask(this).execute();//taken object for asyntask class.
class GetTask extends AsyncTask<Object, Void, String> {
{
ProgressDialog progressDialog;
void GetTask(Context cntxt)
{
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(cntxt); //taking object for progress dialog
mDialog.setMessage("Please wait...");
mDialog.show(); //Displaying progressDialog
}
#Override
protected String doInBackground(Object... params) {
//do the background process
return ""; you can return string value
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (mDialog != null) {
mDialog.dismiss();//close the progress Dialog
}
}
}
You want a ProgressDialog. Refer to this link
use a constructor in DownloadWebPageTask to initialize the context and use that context in dialog.
or use yourclass.this in
dialog = new ProgressDialog(yourclass.this);
Progress dialog
private ProgressDialog dialog;
public void showProgress () {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Please wait");
dialog.show();
}
Use asynchronous task for downloding...
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
//Do your downloading task
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
}
}
Call progress dialog before executing download task
showProgress();
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.url.com" });