Difficulties with dispalying progressdialog - android

I need to display progrees dialog. It is quite simple, however I am absolutly required to wait untill asynctask will finish. That exopse some difficulties to me. To wait for completion of asynctask method .get() is used. But this method blocks my progress dialog.
So, how can I unblock progressdialog with get or what can replace .get()?
I am calling operation in a following way:
Operation o = new Operation();
o.execute(params);
try {
o.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
class Operation
class Operation extends AsyncTask<String, Void, JSONObject> {
ProgressDialog pd;
Context con;
#Override
protected void onPreExecute() {
pd = new ProgressDialog(app);
pd.setOwnerActivity(app);
pd.setTitle("Идет загрузка...");
pd.setCancelable(true);
pd.show();
}
#Override
protected JSONObject doInBackground(String... option) {
/*
some job
*/
return json;
}
#Override
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
pd.dismiss();
/*
some job
*/
}
}

Don't use .get() as you have seen it blocks the UI. You can use getStatus() if you need to check if the task is finished. Removing .get() should allow your ProgressDialog to show. If you have code that must wait until the AsyncTask is finished then put it in onPostExecute() or call a function from there
If you need to reference something in the MainActivity from the AsyncTask after it has finished, simply create a constructor to take a reference of your Activity and pass context to your constructor
Operation o = new Operation(this);
and reference it in constructor
lass Operation extends AsyncTask<String, Void, JSONObject> {
ProgressDialog pd;
Context con;
Activity act;
public Operator(Activity curAct)
{
act = curAct; // can use this reference to access methods in your Activity
}

try to use this way
private ProgressDialog dialog=null;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(this, "", "Please! Wait...",true);
}
#Override
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
dialog.dismiss();
// use here code
}

You might want to change your code to something like this.
Wrap the code you want to run afterwards in a runnable and pass it to your async task.
Runnable onEnd = new Runnable(){
//code to run after the task has completed
}
Operation o = new Operation(onEnd);
o.execute(params);
And here is the modified Operation class.
class Operation extends AsyncTask<String, Void, JSONObject> {
ProgressDialog pd;
Context con;
Runnable afterwards = null;
Operation(Runnable afterwards){
this.afterwards = afterwards ;
}
#Override
protected void onPreExecute() {
pd = new ProgressDialog(app);
pd.setOwnerActivity(app);
pd.setTitle("Идет загрузка...");
pd.setCancelable(true);
pd.show();
}
#Override
protected JSONObject doInBackground(String... option) {
/*
some job
*/
return json;
}
#Override
protected void onPostExecute(JSONObject result) {
super.onPostExecute(result);
pd.dismiss();
/*
some job
*/
if (afterwards != null)
afterwards.run();
}
}
Note the afterwards.run() in onPostExecute.

Related

Asynchronous task is executed 2 times because of the poor quality of the internet-

I have an asynchronous task in Android Studio, to send and receive data from a server as follows.
private class myTask extends AsyncTask<Void, Void, Integer> {
Exception excepccion;
protected void onPreExecute() {
super.onPreExecute();
Mensaje.mensajeConectandoseSicoy(actMetodoPago,getString(R.string.msg_conexion_sicoy));
}
#Override
protected Integer doInBackground(Void... params) {
try {
return new Servidor().guardarObtnerInfoServidorSicoy(ACCION_PAGAR_PEDIDO);
} catch (Exception e2) {
excepccion = e2;
return -1;
}
}
#Override
protected void onPostExecute(Integer respuesta) {
Mensaje.detenerMensajeConectandoseSicoy();
...
}
Where:
public static void mensajeConectandoseSicoy(Context context, String mensaje){
pd = new ProgressDialog(context);
pd.setMessage(mensaje);
pd.setCancelable(false);
Handler pdCanceller = new Handler();
pd.show();
}
public static void detenerMensajeConectandoseSicoy(){
if (pd.isShowing()){
pd.dismiss();
}
}
This process works very well until a user reported problems and discovered that their internet is of very poor quality.
When the task is running onPostExecute, that is, when the server has already responded, it is again executed onPreExecute, and this triggers a series of errors.
I solved it by putting a Boolean type flag variable, to avoid the problem.
My question is:
Is there a way to do that control in a better way?

doInBackground is not getting called sometimes Android

In my application, there are multiple asynctasks. Please let me know why doInBackground of an asynctask sometimes does not getting called. Its onPreExecute method gets called. Is there any issue because of multiple asynctasks or something else?
/* ASync class for test table */
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
If your project has multiple asynctasks you must check that there is a limit of asynctasks that can be executed. When you create a new AsyncTask it will be added on a Pool and will be execute only when is possible.
Check this answer:
Multitasking on android
And the docs: ThreadPoolExecutor
Here is an example on how properly handle multiple AsyncTasks AsyncTaskManager
OnPreExecute() gets called on the UI thread and doInBackground() is called on the background thread.
There is one dedicated background thread for the async task. This behaviour can be changed if you want to.
http://android-er.blogspot.in/2014/04/run-multi-asynctask-as-same-time.html
Now, say you have multiple instances of async task and I'm assuming you are calling execute() to run the async tasks. This will trigger all the preExecute immediately since UI thread is free but for the doInBackground it will triggered one by one. Hence it may take some time for the next async task to start.
doInBackground should run on a loop using a Boolean to check before execution. Before your Task is being executed, set a global boolean (may be true/false) depends on which you prefer and values add on thread should call runOnUiThread.
startExect = true;
new TestAsynch().execute();
then change this
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
to this
public class TestAsynch extends AsyncTask<String, Void, String> {
String result1 = null;
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
result1=API_Manager.getInstance().sendTestData(userName);
while (startExecute) {
Thread exe = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5);
}
catch( Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if(result1 != null) {
// save in db
}
}
});
}
}); exe.start();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}

onPostExecute Outer ASyncTask in nested ASyncTasks called before all work finished

I have a few async tasks that get data from JSON services.
In the onPreExecute of the outside task I want to show a progressDialog.
I want to dismiss it in onPostExecute and start another activity.
The problem is that there is still data loading when my onPostExecute is called, so the next activity is executed without the needed data.
Is this normal behavior?
Is there a workaround?
class GetDataAsync extends AsyncTask<Integer, Integer, Integer> {
#Override
protected void onPreExecute() {
Log.d("startupflow","GetDataAsync onPreExecute");
progress = new ProgressDialog(Login.this);
progress.setMessage("Loading...");
progress.show();
super.onPreExecute();
}
#Override
protected Integer doInBackground(Integer... params) {
Log.d("startupflow","GetDataAsync doInBackground");
GetData getData = new GetData();
getData.LoadAllData(getApplicationContext(), token, client);
return null;
}
#Override
protected void onPostExecute(Integer integer) {
Log.d("startupflow","GetDataAsync onPostExecute");
if (progress.isShowing()) {
progress.dismiss();
}
Intent intent = new Intent(Login.this, Admin.class);
startActivity(intent);
super.onPostExecute(integer);
}
In the GetData class:
public void LoadAllData(Context context, Token token, OAuth2Client client) {
this.context = context;
this.token = token;
this.client = client;
new AllDataAsync().execute();
}
class AllDataAsync extends AsyncTask<Integer, Integer, Integer> {
#Override
protected Integer doInBackground(Integer... params) {
try {
Log.d("GetData", "In AllDataAsyc, do in background");
GetClientandToken(token, client);
Log.d("GetData", "getcompanyanddatatapstask");
new GetCompanyAndDataTapsTask().execute();
Log.d("GetData", "getslidestask");
new GetSlidesTask().execute();
} catch (Exception e) {
e.printStackTrace();
errorOccurred = true;
}
return null;
}
}
The Log:
08-12 11:27:37.515 D/startupflow﹕ GetDataAsync onPreExecute
08-12 11:27:37.562 D/startupflow﹕ GetDataAsync doInBackground
08-12 11:27:37.601 D/startupflow﹕ GetDataAsync onPostExecute
08-12 11:27:40.132 D/startupflow﹕ all data saved
The reason your first async is starting the activity early is because it is only starting the second data-loading async. AsyncTasks work on different threads (hence asynchronous), meaning they don't wait for each other.
What you can do is call a function in the postExecute of the data-loading async to notify your activity that it's done. E.g. add an onFinishedLoadingData function, and call that in your postExecute. You can start your new activity there.

ProgressBar does not show immediately in android

I have a base class of an activity and a sub class which extends the base class. The superclass has a async task to perform some action. I call this by running it on the ui thread since otherwise it throws an IllegalInitializerError:
superclass.this.runOnUiThread(new Runnable() {
public void run() {
String p="";
try {
p=new asynctasker().execute().get();
}
}
}
In my async task:
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
//showDialog();
Log.d("Now","Inside right now");
dialog = ProgressDialog.show(class_create_event.this, "Loading1", "Please Wait");
}
However the dialog is displayed almost at the end of the request. The I am in part is printed correctly. I know that something is blocking my ui thread. But if I dont call the async task from the UI thread it throws an illegal initializer error. Is there any way out?
You don't need to have UIthread for calling AsyncTask
Call it like this way
FetchRSSFeeds async = new FetchRSSFeeds();
async.execute();
private class FetchRSSFeeds extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
/** progress dialog to show user that the backup is processing. */
/** application context. */
protected void onPreExecute() {
this.dialog.setMessage(getResources().getString(
R.string.Loading_String));
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
try {
// Fetch the RSS Feeds from URL
// do background process
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
// Setting data to list adaptar
setListData();
}
}
}

AsyncTask Android example

I was reading about AsyncTask, and I tried the simple program below. But it does not seem to work. How can I make it work?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
}
I am just trying to change the label after 5 seconds in the background process.
This is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
My full answer is here, but here is an explanatory image to supplement the other answers on this page. For me, understanding where all the variables were going was the most confusing part in the beginning.
Ok, you are trying to access the GUI via another thread. This, in the main, is not good practice.
The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.
preExecute() and postExecute() offer you access to the GUI before and after the heavy lifting occurs in this new thread, and you can even pass the result of the long operation to postExecute() to then show any results of processing.
See these lines where you are later updating your TextView:
TextView txt = findViewById(R.id.output);
txt.setText("Executed");
Put them in onPostExecute().
You will then see your TextView text updated after the doInBackground completes.
I noticed that your onClick listener does not check to see which View has been selected. I find the easiest way to do this is via switch statements. I have a complete class edited below with all suggestions to save confusion.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
AsyncTask<?, ?, ?> runningTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.button1);
// Because we implement OnClickListener, we only
// have to pass "this" (much easier)
btn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// Detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
if (runningTask != null)
runningTask.cancel(true);
runningTask = new LongOperation();
runningTask.execute();
break;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// Cancel running task(s) to avoid memory leaks
if (runningTask != null)
runningTask.cancel(true);
}
private final class LongOperation extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We were cancelled; stop sleeping!
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// You might want to change "executed" for the returned string
// passed into onPostExecute(), but that is up to you
}
}
}
I'm sure it is executing properly, but you're trying to change the UI elements in the background thread and that won't do.
Revise your call and AsyncTask as follows:
Calling Class
Note: I personally suggest using onPostExecute() wherever you execute your AsyncTask thread and not in the class that extends AsyncTask itself. I think it makes the code easier to read especially if you need the AsyncTask in multiple places handling the results slightly different.
new LongThread() {
#Override public void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}.execute("");
LongThread class (extends AsyncTask):
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Executed";
}
Concept and code here
I have created a simple example for using AsyncTask of Android. It starts with onPreExecute(), doInBackground(), publishProgress() and finally onProgressUpdate().
In this, doInBackground() works as a background thread, while other works in the UI Thread. You can't access an UI element in doInBackground(). The sequence is the same as I have mentioned.
However, if you need to update any widget from doInBackground, you can publishProgress from doInBackground which will call onProgressUpdate to update your UI widget.
class TestAsync extends AsyncTask<Void, Integer, String> {
String TAG = getClass().getSimpleName();
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
for (int i=0; i<10; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";
}
protected void onProgressUpdate(Integer...a) {
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG + " onPostExecute", "" + result);
}
}
Call it like this in your activity:
new TestAsync().execute();
Developer Reference Here
Move these two lines:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
out of your AsyncTask's doInBackground method and put them in the onPostExecute method. Your AsyncTask should look something like this:
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(5000); // no need for a loop
} catch (InterruptedException e) {
Log.e("LongOperation", "Interrupted", e);
return "Interrupted";
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}
How to memorize the parameters used in AsyncTask?
Don't
If you are new to AsyncTask then it is very common to get confused while writing an AsyncTask. The main culprits are the parameters used in the AsyncTask, i.e., AsyncTask<A, B, C>. Based on the A, B, C (arguments) signature of the methods differs which makes things even more confusing.
Keep it simple!
The key is don't memorize. If you can visualize what your task really needs to do then writing the AsyncTask with the correct signature at the first attempt would be a piece of cake. Just figure out what your Input, Progress, and Output are, and you will be good to go.
So what is an AsyncTask?
AsyncTask is a background task that runs in the background thread. It takes an Input, performs Progress and gives an Output.
I.e., AsyncTask<Input, Progress, Output>.
For example:
What is the relationship with methods?
Between AsyncTask and doInBackground()
doInBackground() and onPostExecute(),onProgressUpdate()` are also
related
How to write that in the code?
DownloadTask extends AsyncTask<String, Integer, String>{
// Always same signature
#Override
public void onPreExecute()
{}
#Override
public String doInbackGround(String... parameters)
{
// Download code
int downloadPerc = // Calculate that
publish(downloadPerc);
return "Download Success";
}
#Override
public void onPostExecute(String result)
{
super.onPostExecute(result);
}
#Override
public void onProgressUpdate(Integer... parameters)
{
// Show in spinner, and access UI elements
}
}
How will you run this Task?
new DownLoadTask().execute("Paradise.mp3");
Background / Theory
AsyncTask allows you to run a task on a background thread, while publishing results to the UI thread.
The user should always able to interact with the app so it is important
to avoid blocking the main (UI) thread with tasks such as
downloading content from the web.
This is why we use an AsyncTask.
It offers a straightforward interface by wrapping the UI thread message queue and handler that allow you to send and process runnable objects and messages from other threads.
Implementation
AsyncTask is a generic class. (It takes parameterized types in its constructor.)
It uses these three generic types:
Params - the type of the parameters sent to the task upon execution.
Progress - the type of the progress units published during the background computation.
Result - the type of the result of the background computation.
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
These three parameters correspond to three primary functions you can override in AsyncTask:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
To execute AsyncTask
Call execute() with parameters to be sent to the background task.
What Happens
On main/UI thread, onPreExecute() is called.
To initialize something in this thread. (E.g. show a progress bar on the user interface.)
On a background thread, doInBackground(Params...) is called.
(Params were passed via execute.)
Where the long-running task should happen.
Must override at least doInBackground() to use AsyncTask.
Call publishProgress(Progress...) to update the user interface with a display of progress (e.g. UI animation or log text printed) while the background computation is still executing.
Causes onProgressUpdate() to be called.
On the background thread a result is returned from doInBackground().
(This triggers the next step.)
On main/UI thread, onPostExecute() is called with the returned result.
Examples
In both examples the "blocking task" is a download from the web.
Example A downloads an image and displays it in an ImageView, while
Example B downloads some files.
Example A
The doInBackground() method downloads the image and stores it in an object of type BitMap. The onPostExecute() method takes the bitmap and places it in the ImageView.
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bitImage;
public DownloadImageTask(ImageView bitImage) {
this.bitImage = bitImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mBmp = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mBmp = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mBmp;
}
protected void onPostExecute(Bitmap result) {
bitImage.setImageBitmap(result);
}
}
Example B
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Example B execution
new DownloadFilesTask().execute(url1, url2, url3);
When an asynchronous task is executed, the task goes through four steps:
onPreExecute()
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Below is a demo example:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled())
break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
And once you created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Shortest example for just doing something asynchronously:
class MyAsyncTask extends android.os.AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
// Do something asynchronously
return null;
}
}
To run it:
(new MyAsyncTask()).execute();
When you are in the worker thread, you can not directly manipulate UI elements on Android.
When you are using AsyncTask please understand the callback methods.
For example:
public class MyAyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
// Here you can show progress bar or something on the similar lines.
// Since you are in a UI thread here.
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// After completing execution of given task, control will return here.
// Hence if you want to populate UI elements with fetched data, do it here.
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// You can track you progress update here
}
#Override
protected Void doInBackground(Void... params) {
// Here you are in the worker thread and you are not allowed to access UI thread from here.
// Here you can perform network operations or any heavy operations you want.
return null;
}
}
FYI:
To access the UI thread from a worker thread, you either use runOnUiThread() method or post method on your view.
For instance:
runOnUiThread(new Runnable() {
textView.setText("something.");
});
or
yourview.post(new Runnable() {
yourview.setText("something");
});
This will help you know the things better. Hence in you case, you need to set your textview in the onPostExecute() method.
I would recommend making your life easier by using this library for background works:
https://github.com/Arasthel/AsyncJobLibrary
It's this simple...
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
#Override
public void doOnBackground() {
startRecording();
}
});
Sample Async Task with POST request:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();
class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
String URL;
List<NameValuePair> parameters;
private ProgressDialog pDialog;
public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
{
this.URL = url;
this.parameters = params;
}
#Override
protected void onPreExecute()
{
pDialog = new ProgressDialog(LoginActivity.this);
pDialog.setMessage("Processing Request...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... params)
{
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
HttpPost httpPost = new HttpPost(URL);
if (parameters != null)
{
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity);
} catch (Exception e)
{
}
return "";
}
#Override
protected void onPostExecute(String result)
{
pDialog.dismiss();
try
{
}
catch (Exception e)
{
}
super.onPostExecute(result);
}
}
Update: March 2020
According to Android developer official documentation, AsyncTask is now deprecated.
It's recommended to use kotlin corourines instead. Simply, it allows you to write asynchronous tasks in a sequential style.
Simply:
LongOperation MyTask = new LongOperation();
MyTask.execute();
You need to declare the button onclicklistener. Once clicked, it calls AsyncTask class DownloadJson.
The process will be shown below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new DownloadJson().execute();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJson extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
newlist = new ArrayList<HashMap<String, String>>();
json = jsonParser.makeHttpRequest(json, "POST");
try {
newarray = new JSONArray(json);
for (int i = 0; i < countdisplay; i++) {
HashMap<String, String> eachnew = new HashMap<String, String>();
newobject = newarray.getJSONObject(i);
eachnew.put("id", newobject.getString("ID"));
eachnew.put("name", newobject.getString("Name"));
newlist.add(eachnew);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
newlisttemp.addAll(newlist);
NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
newpager.setAdapter(newadapterpager);
}
}
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Do code here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
#Override
protected void onCancelled() {
super.onCancelled();
progressDialog.dismiss();
Toast toast = Toast.makeText(
getActivity(),
"An error is occurred due to some problem",
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
}
While working with AsyncTask, it is necessary to create a class-successor and in it to register the implementation of methods necessary for us. In this lesson we will look at three methods:
doInBackground - will be executed in a new thread, and here we solve all our difficult tasks. Because a non-primary thread does not have access to the UI.
onPreExecute - executed before doInBackground and has access to the UI
onPostExecute - executed after doInBackground (does not work if AsyncTask was canceled - about this in the next lessons) and has access to the UI.
This is the MyAsyncTask class:
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
tvInfo.setText("Start");
}
#Override
protected Void doInBackground(Void... params) {
// Your background method
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
tvInfo.setText("Finish");
}
}
And this is how to call in your Activity or Fragment:
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
AsyncTask:
public class MainActivity extends AppCompatActivity {
private String ApiUrl="your_api";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask myTask=new MyTask();
try {
String result=myTask.execute(ApiUrl).get();
Toast.makeText(getApplicationContext(),result,Toast.LENGTH_SHORT).show();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class MyTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
String result="";
HttpURLConnection httpURLConnection=null;
URL url;
try {
url=new URL(strings[0]);
httpURLConnection=(HttpURLConnection) url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
InputStreamReader reader=new InputStreamReader(inputStream);
result=getData(reader);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public String getData(InputStreamReader reader) throws IOException{
String result="";
int data=reader.read();
while (data!=-1){
char now=(char) data;
result+=data;
data=reader.read();
}
return result;
}
}
}
Sample AsyncTask example with progress
import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
Button btn;
ProgressBar progressBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
progressBar = (ProgressBar)findViewById(R.id.pbar);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
new LongOperation().execute("");
break;
}
}
private class LongOperation extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
Log.d("AsyncTask", "doInBackground");
for (int i = 0; i < 5; i++) {
try {
Log.d("AsyncTask", "task "+(i + 1));
publishProgress(i + 1);
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Completed";
}
#Override
protected void onPostExecute(String result) {
Log.d("AsyncTask", "onPostExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
progressBar.setProgress(0);
}
#Override
protected void onPreExecute() {
Log.d("AsyncTask", "onPreExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onPreExecute");
progressBar.setMax(500);
progressBar.setProgress(0);
}
#Override
protected void onProgressUpdate(Integer... values) {
Log.d("AsyncTask", "onProgressUpdate "+values[0]);
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onProgressUpdate "+values[0]);
ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
animation.setDuration(1000);
animation.setInterpolator(new LinearInterpolator());
animation.start();
}
}
}
if you open AsyncTask class you can see below code.
public abstract class AsyncTask<Params, Progress, Result> {
#WorkerThread
protected abstract Result doInBackground(Params... params);
#MainThread
protected void onPreExecute() {
}
#SuppressWarnings({"UnusedDeclaration"})
#MainThread
protected void onPostExecute(Result result) {
}
}
AsyncTask features
AsyncTask is abstract class
AsyncTask is have 3 generic params.
AsyncTask has abstract method of doInBackground, onPreExecute, onPostExecute
doInBackground is WorkerThread (you can't update UI)
onPreExecute is MainThread
onPostExecute is MainThread (you can update UI)
example
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
#Override
protected Post doInBackground(Void... params) {
try {
ApiClient defaultClient = Configuration.getDefaultApiClient();
String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
Bearer.setApiKey(authorization);
PostApi apiInstance = new PostApi();
String id = "1"; // String | id
Integer commentPage = 1; // Integer | Page number for Comment
Integer commentPer = 10; // Integer | Per page number For Comment
Post result;
try {
result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
} catch (ApiException e) {
e.printStackTrace();
result = new Post();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return new Post();
}
}
#Override
protected void onPostExecute(Post post) {
super.onPostExecute(post);
if (post != null) {
mEmailView.setText(post.getBody());
System.out.print(post);
}
}
};
asyncTask.execute();
}
Change your code as given below:
#Override
protected void onPostExecute(String result) {
runOnUiThread(new Runnable() {
public void run() {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
}
});
}

Categories

Resources