AsyncTask ProgressDialog stopped, after callback - android

this my task:
public class GetTask extends AsyncTask<String, Void, JSONObject> {
// callback
private Activity activity;
private AsyncTaskCompleteListener callback;
private AppUtils appUtils;
private ProgressDialog dialog;
private String object;
public GetTask(Activity act){
this.activity = act;
this.callback = (AsyncTaskCompleteListener)act;
}
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(activity);
dialog.setTitle("Load...");
dialog.setMessage("Data...");
dialog.setCancelable(true);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
cancel(false);
}
});
dialog.show();
}
protected JSONObject doInBackground(String... url) {
String link = url[0];
object = AppUtils.cutStringAfter(link);
link = AppUtils.cutStringBefore(link);
return AppUtils.getJSONData(link);
}
protected void onPostExecute(JSONObject result) {
if (null != dialog && dialog.isShowing()) {
dialog.dismiss();
}
super.onPostExecute(result);
callback.onTaskComplete(result, object);
}
#Override
protected void onCancelled()
{
if (this.dialog != null) {
this.dialog.dismiss();
}
}
}
onTaskComplete call other procedure for parse data:
#Override
public void onTaskComplete(JSONObject result, String object) {
try {
setDBDATA(result, object);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Dialog dismissed after complete procedure setDBDATA(result, object);, while works setDBDATA, ProgressDialog freezes.
How close ProgressDialog before callback procedure, or prevent freeze him?

in opPostExecute() set an onDismissListener() on your ProgressDialog and call the call back method from onDismiss()
Something like this:-
dialog.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
callback.onTaskComplete(result, object);
}
});
Hope this helps.

If setDBDATA will take long time, then move it to doInBackground.

Related

Reshow a progress dialog from Async Task if it gets dismissed

I have a progress dialog that shows how many files are left for uploading in my Async Task and the user can dismiss this dialog if he wants to. However I want to have a button that will be able to show again that progress dialog at its current stage and I don't know how to do that since you I can't just create a function in the Async Task and call it from a different activity. Any thoughts?
You can make a singleton class to handle the Async Task progress which holds only one listener (the Activity who wants to listen for the progress of your AsyncTask).
Your Singleton class can be like below:
public class ProgressDialogUtil {
public interface ProgressDialogUtilListener{
void showProgressDialog();
void dismissProgressDialog();
void updateProgressDialog(int value);
void setProgressDialogMessage(String message);
}
private ProgressDialogUtilListener listener;
private static ProgressDialogUtil mInstance;
public static ProgressDialogUtil getInstance() {
if (mInstance == null) {
synchronized (ProgressDialogUtil.class) {
if (mInstance == null) {
mInstance = new ProgressDialogUtil();
}
}
}
return mInstance;
}
public void setListener(ProgressDialogUtilListener listener) {
this.listener = listener;
}
public void showProgressDialog(){
if(listener!=null)
listener.showProgressDialog();
}
public void dismissProgressDialog(){
if(listener!=null)
listener.dismissProgressDialog();
}
public void updateProgressDialog(int value){
setProgressDialogMessage("Files Downloaded: "+ value);
if(listener!=null)
listener.updateProgressDialog(value);
}
public void setProgressDialogMessage(String message){
if(listener!=null)
listener.setProgressDialogMessage(message);
}
}
Then you can use this Singleton class (ProgressDialogUtil) in your AsyncTask like below to inform for any update occurred:
public class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {
public final ProgressDialogUtil progressDialogUtil;
public MyAsyncTask(ProgressDialogUtil progressDialogUtil){
this.progressDialogUtil = progressDialogUtil;
}
#MainThread
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialogUtil.setProgressDialogMessage("Start Download files..");
progressDialogUtil.showProgressDialog();
}
#WorkerThread
#Override
protected Boolean doInBackground(Void... params) {
//download your files here in the Background Thread...
//below is a sample loop
for (int i=0; i <= 50; i++) {
try {
Thread.sleep(1000);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
return true;
}
#MainThread
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialogUtil.updateProgressDialog(values[0]);
}
#MainThread
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialogUtil.setProgressDialogMessage("Finished Download!");
progressDialogUtil.dismissProgressDialog();
}
}
Then in your first Activity where you start the AsyncTask you can create a new instance of your Progress Dialog and set a listener ProgressDialogUtilListener to listen for any AsyncTask progress to show/hide/update the Progress Dialog like below:
ProgressDialog pd = new ProgressDialog(this);
ProgressDialogUtil progressDialogUtil = ProgressDialogUtil.getInstance();
progressDialogUtil.setListener(new ProgressDialogUtil.ProgressDialogUtilListener()
{
#Override
public void showProgressDialog() {
if (!pd.isShowing())
pd.show();
}
#Override
public void dismissProgressDialog() {
if (pd.isShowing())
pd.dismiss();
}
#Override
public void updateProgressDialog(int value) {
pd.setProgress(value);
}
#Override
public void setProgressDialogMessage(String message) {
pd.setMessage(message);
}
});
new MyAsyncTask(progressDialogUtil).execute();
Finally when you navigate to a new Activity you can use the same Singleton Instance ProgressDialogUtil and change the listener to the new Activity now all AsyncTask events will be handled to the new Activity and the dialog can be opened/closed via a button through this singleton class like below:
ProgressDialog pd = new ProgressDialog(this);
ProgressDialogUtil progressDialogUtil = ProgressDialogUtil.getInstance();
progressDialogUtil.setListener(new ProgressDialogUtil.ProgressDialogUtilListener()
{
#Override
public void showProgressDialog() {
if (!pd.isShowing())
pd.show();
}
#Override
public void dismissProgressDialog() {
if (pd.isShowing())
pd.dismiss();
}
#Override
public void updateProgressDialog(int value) {
pd.setProgress(value);
}
#Override
public void setProgressDialogMessage(String message) {
pd.setMessage(message);
}
});
//Show Progress Dialog from a Button Click
showButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressDialogUtil.showProgressDialog();
}
});
//Dismiss Progress Dialog from a Button Click
dismissButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressDialogUtil.dismissProgressDialog();
}
});
You can have a Live data in any singleton class like below to share the progress between activities.
object ProgressHelper {
val progress = MutableLiveData<Int>()
}
Then update the progress values from the AsyncTask like below:
override fun onProgressUpdate(vararg values: Int?) {
super.onProgressUpdate(*values)
ProgressHelper.progress.value = 100
}
In your activity you can observe the progress like below:
ProgressHelper.progress.observe(this, Observer {
val progress = it
})

Login Screen showing progressdialog and allow screen orientation change

Hello i am trying to implement a log in screen showing a progress dialog and allowing the phone to rotate.
I want to ask what is the best way to do that (IntentService, AsyncTask,Service) and allowing the phone to rotate?
I read a lot answers saying different things using an empty fragment with AsyncTask etc.
You can do something like that in manifest to allow rotation:
<application
android:allowBackup="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"/>
Then you can catch the rotation with this snipet inside your activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.v(this.getClass().getName(), "onConfigurationChanged()");
}
To do an asynctask with progress dialog, this snipet should give you a ligth:
private ProgressDialog pDialog;
private class MyAsync extends AsyncTask<String, Void, String> {
Activity context;
public MyAsync (Activity context) {
this.context = context;
}
#Override
protected void onPreExecute(){
super.onPreExecute();
pdia = new ProgressDialog(context);
pdia.setMessage("Loading...");
pdia.show();
}
#Override
protected String doInBackground(String... urls) {
...
//do your login scheme
...
//context.methods()
return "ok";
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
if(result!=null && result.equals("ok")){
//login was successfully done
} else {
//login has failed
}
}
}
And to use this asynctask you shoud call:
new MyAsync(this).execute(null, null , null);
By the way this is your activity/fragment.
Try adding this attribute android:configChanges="orientation" to your Activity element in the AndroidManifest.xml file.
show a ProgressDialog in the onPreExecute method of an AsyncTask object and canceling the ProgressDialog in the onPostExecute method. doInBackground method is running When change the orientation.
Refer to http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html for a detailed answer.
Basically, you can use fragment with setRetainInstance set to true inside your LoginActivity so that it doesn't get destroyed when activity is recreated during orientation change.
Sample Code :
public class AsyncFragment extends Fragment {
private LoginTask mTask;
private AsyncTaskListener mListener;
private static final String TAG = "AsyncFragment";
private boolean isTaskRunning = false;
private ProgressDialog mProgressDialog;
FrameLayout mLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
mTask = new LoginTask();
mTask.execute();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLayout = new FrameLayout(getActivity());
mLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
if(isTaskRunning) {
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.show();
}
return mLayout;
}
#Override
public void onDestroyView() {
if(mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
super.onDestroyView();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (AsyncTaskListener) context;
} catch (ClassCastException e) {
Log.d(TAG, "Class not instance of AsyncTaskListener");
}
}
#Override
public void onDetach() {
mListener = null;
super.onDetach();
}
private class LoginTask extends AsyncTask<Void,Integer,Void> {
#Override
protected Void doInBackground(Void... params) {
if(mListener != null) {
mListener.onBackground();
}
SystemClock.sleep(10000);
return null;
}
#Override
protected void onPreExecute() {
isTaskRunning = true;
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.show();
if(mListener != null) {
mListener.onPreExecute();
}
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mListener != null) {
mListener.onPostExecute();
}
isTaskRunning = false;
if(mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(mListener != null) {
mListener.onProgressUpdate(values[0]);
}
}
#Override
protected void onCancelled() {
super.onCancelled();
if(mListener != null) {
mListener.onCancelled();
}
}
}
//Listener to notify for async task callbacks
public interface AsyncTaskListener{
void onPreExecute();
void onPostExecute();
void onCancelled();
void onBackground();
void onProgressUpdate(int progress);
}
}
LoginActivity
public class MainActivity extends AppCompatActivity implements AsyncFragment.AsyncTaskListener{
private static final String FRAGMENT_TAG = "asyncFragment";
private static final String TAG = "MainActivity";
private AsyncFragment mAsyncFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
mAsyncFragment = (AsyncFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (mAsyncFragment == null) { //fragment was retained during orientation change
mAsyncFragment = new AsyncFragment();
fm.beginTransaction().add(mAsyncFragment, FRAGMENT_TAG).commit();
}
}
#Override
public void onPreExecute() {
Log.d(TAG, "onPreExecute: ");
}
#Override
public void onPostExecute() {
Log.d(TAG, "onPostExecute: ");
}
#Override
public void onCancelled() {
Log.d(TAG, "onCancelled: ");
}
#Override
public void onBackground() {
Log.d(TAG, "onBackground: ");
}
#Override
public void onProgressUpdate(int progress) {
Log.d(TAG, "onProgressUpdate: ");
}
Have you tried this?
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize">
</activity>
This way the activity will not be recreated. but you can detect the screen orientation using onConfigurationChanged()

Progress dialog in AsyncTask do not show up

I know there was similiar problem to this, but I still haven't found an answer. The problem is that progress dialog for this long operation won't show up, but still process is being done. I think there is problem with the context, but dunno how to solve this.
public class MainActivity extends Activity {
Utilities uti = new Utilities();
SharedPreferences prefs = null;
private ContactServiceActivity contactService;
ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactService = new ContactServiceActivity(getApplicationContext());
doFirstRun();
Intent i = new Intent(getBaseContext(), ContactListActivity.class);
startActivity(i);
}
private void doFirstRun() {
SharedPreferences settings = getSharedPreferences("pl.stxnext.stxcontactsync", MODE_PRIVATE);
if (settings.getBoolean("isFirstRun", true)) {
new firstRunTask().execute();
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("isFirstRun", false);
editor.commit();
}
}
private class firstRunTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setTitle("Trwa synchronizacja danych");
mProgressDialog.setMessage("Może to zająć chwilę, proszę czekać.");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
contactService.getAssetsAtFirstRun();
return null;
}
#Override
protected void onPostExecute(Void result) {
mProgressDialog.dismiss();
uti.showToast(getBaseContext(), "Zapisano kontakty.");
}
}
}
create one constructor like:
Context _context;
public firstRunTask(Context context)
{
_context=context;
}
and use this _context for context in dialog.
Try like this
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// Do something
return "Executed";
}
#Override
protected void onPostExecute(String result) {
if(mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
}
#Override
protected void onPreExecute() {
ShowLoading();
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
private void ShowLoading(){
mProgressDialog = new ProgressDialog(this);
//mProgressDialog.setMessage("Loading Please wait ....");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
You are starting an activity after starting the asyctask by calling doFirstRun(); , and thus you are not seeing the progressdialog created. if you remove/comment the startActivity portion as follows, it should work:
doFirstRun();
// comment the following
//Intent i = new Intent(getBaseContext(), ContactListActivity.class);
//startActivity(i);
If you still want to start that activity anyway, then you should start the asynctask after that.
Do this-
private class firstRunTask extends AsyncTask<Void, Void, Void> {
ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog=ProgressDialog.show(MainActivity.this, "Trwa synchronizacja danych", "Może to zająć chwilę, proszę czekać.");
}
#Override
protected Void doInBackground(Void... params) {
contactService.getAssetsAtFirstRun();
return null;
}
#Override
protected void onPostExecute(Void result) {
if(mProgressDialog != null)
{
if(mProgressDialog.isShowing())
{
mProgressDialog.dismiss();
uti.showToast(getBaseContext(), "Zapisano kontakty.");}
}
}

ProgressBar setVisibility doesn't show at the right time

public void generateNumbers(){
progressBar.setVisibility(View.VISIBLE);
while(){
//approximately 5 second long procedure
}
printNumbers();
progressBar.setVisibility(View.GONE);
}
I want that the progress bar is visible when this long procedure in while loop is running and then dissapear. The code like this shown progressBar after the loop is finished and then also dissapear (setVisiblity(GONE)).
In while loop i don't have any new threads or AsyncTask
Use an asynctask like this
public class asyncTask extends AsyncTask<String, Void, String> {
private Context context;
private ProgressDialog dialog;
public asyncTask(Context cxt) {
context = cxt;
dialog = new ProgressDialog(context);
}
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.setTitle("Please Wait...");
dialog.show();
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
}
#Override
protected String doInBackground(String... arg0) {
//Put your code here
}
}

Adding a progress bar to my application while loading data from from website

I have a simple class which extends activiy like this
public class About extends Activity
{
private ProgressDialog pdia;
private TextView tvAbout;
private WebView vwAbout;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.about);
vwAbout = (WebView)findViewById(R.id.vwViewAbout);
String content = new String();
try {
URL url = new URL("http://xxx.prodevAbout.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null)
{
content+=str + "\n";
vwAbout.loadData(content, "text/html", null);
}
in.close();
} catch (Exception e)
{
vwAbout.loadData("error message", "text/html", null);
}
}
}
and what I want to do is I want to add a progressbar while loading content from website and I found this code
private ProgressDialog pdia;
#Override
protected void onPreExecute(){
super.onPreExecute();
pdia = new ProgressDialog(yourContext);
pdia.setMessage("Loading...");
pdia.show();
}
#Override
protected void onPostExecute(String result){
super.onPostExecute(result);
pdia.dismiss();
}
and added this code but onPreExecute method cannot be resolved What should I do ?
Thanks;
The way which I am adding progress dialogs in my apps (and I've never had any problems till now) is like this :
Runnable runable = new Runnable() {
#Override
public void run() {
SofiaLiveCafeActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB){
progressDialog = new ProgressDialog(SofiaLiveCafeActivity.this, ProgressDialog.THEME_HOLO_LIGHT);
} else {
progressDialog = new ProgressDialog(SofiaLiveCafeActivity.this);
}
progressDialog.setMessage("Loading! Pleasе wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
});
// CONNECT TO SERVER AND DOWNLOAD DATA
SofiaLiveCafeActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
}
}
};
new Thread(runable).start();
added this code but onPreExecute method cannot be resolved What should
I do ?
onPreExecute not resolved because this is method from AsyncTask so will need to extends AsyncTask class to use onPreExecute change your current code using AsyncTask as :
public class About extends Activity
{
[...your code here...]
public void onCreate(Bundle savedInstanceState)
{
[...your code here...]
// execute AsyncTask as
new LongOperation(About.this).execute("");
}
[...your code here...]
public class WebapiOperation extends AsyncTask<String, Void, String> {
Context context;
WebapiOperation(Context context){
this.context=context;
}
#Override
protected void onPreExecute() {
// show ProgressDialog here
pdia = new ProgressDialog(context);
}
#Override
protected String doInBackground(String... params) {
// make web service access task here
return null;
}
#Override
protected void onPostExecute(String result) {
// ProgressDialog here
}
}

Categories

Resources