I use a lot of AsyncTasks but always like this:
private class connectAsyncTask extends AsyncTask<String, Void, String> {
//Create a Progress Dialog
#Override
protected void onPostExecute(String info) {
//Dismiss the dialog
}
#Override
protected String doInBackground(String... params) {
//complete code to get data to be populated on the view
}
#Override
protected void onPreExecute() {
//Show the dialog
}
But its like showing the progress dialog until I fetch the data and then populate all the View on the layout.
Instead I want it to be like, some data will be sent as Bundle, those can be used to populate their respective views and anything like a ImageView, whose Image is yet to be fetched must show a progress dialog.
Many apps like Amazon etc.., does this. Even the dialogs doesn't have any rectangular backround or text. How to do this?
Related
I want to show some message and a progress bar while my app initializes.
I need to insert some dictionaries of words into a SQLite database the first time my app is run. To do this I have an AsyncTask which opens my SQLiteOpenHelper and closes it again, just so the database initialization is done once.
private class AsyncDbInit extends AsyncTask<Void, Void, Void> {
private Context context;
private Intent intent;
public AsyncDbInit(Context context, Intent intent){
this.context = context;
this.intent = intent;
}
#Override
protected Void doInBackground(Void... params) {
DatabaseHandler db = new DatabaseHandler(this.context);
db.close();
return null;
}
#Override
protected void onPostExecute(Void param) {
context.startActivity(this.intent);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... params) {}
}
This AsyncTask is called in my onCreate() method, but I've also tried to run it from onStart() and onResume() without succes.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dispatcher);
... //some code finding the right intent
new AsyncDbInit(this, nextIntent).execute();
}
Somehow this last line, which calls the AsyncTask, stops my UI from showing up; the screen just stays blank until the AsyncTask is completed and the new activity is started.
When I comment that line out, the UI shows up just fine.
The only thing I can come up with is that the SQLiteOpenHelper somehow blocks the UiThread, but I couldn't find anything about that either.
In the AsyncTask we have some methods. Just like in doInBackground() we do the things we wants to be done in the background and there are two methods also whch are onPreExecute() and onPostExecute(). Create and progress dialog and show the dialog in onPreExecute() method and dismiss it in onPostExecute() method.
Try using AsynTask.executeOnExecutor() with the thread pool executor. If this works, it means something involved with loading your UI is also using an AsyncTask. AsyncTasks by default run sequentially on a single work thread and this can introduce contention. This serial execution is often what you want, but not always.
Does you UI use any libraries to load strings or other content? Can you provide your layout XML?
I have two Activitys (mainActivity & downloadActivity) and I have 2 AsyncTasks in downloadActivity
In downloadActivity first it execute getFileAsyncTask for reading a JSON file for adding some images and create a ListView from images, if user clicks on an image, the downloadAsyncTask was called and it starts to download something from the internet.
My problem is here: when the second AsyncTask is running I go back to mainActivity and comeback again to downloadActivity the first AsyncTask wasn't called until the downloadAsyncTask completed.
public class downloadActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
...
new getFileAsyncTask().execute();
...
}
private class getFileAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//fetch a json file from internet and add images in ListView
return null;
}
}
//there is a Base Adapter class
//if user clicks on an image it calls this downloadAsyncTask.execute()
private class downloadAsyncTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
//download the file
}
}
#Override
protected Void doInBackground(Void... unused) {
//download the file
}
}
note: I want to write something like shopping apps. For example, user can download file and surf into shop to see products .
If you want to run multiple AsyncTasks in parallel, you can call executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) instead of execute() on your task. By default, AsyncTasks run in serial, first come first serve.
Be careful that the two threads do not interact on the same data, this can cause some strange and hard to trace errors.
you can make it in one asynk class that have two methodes first fetch json file wait response in doInBackground ... if it is ok call download file methode. Those methodes will return an httpResponse object
You can override onBackPressed function in activity and finish the current activity before go to previous activity. When again you come to downloadActivity it call it's oncreate method and call first AsynctTask.
Make one class task like:
Declare progress bar globally in main thread.
Now what you have to do is start one async task in main thread like:
public class myactivity extends Activity {
private ProgressDialog _dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_screen);
new abc().execute();
}
class abc extends AsyncTask(String,String,String) {
#Override
protected void onPreExecute() {
_dialog = new ProgressDialog(_ctx);
_dialog.setCancelable(false);
_dialog.setMessage("Loading");
_dialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
#Override
protected void onPostExecute(String result) {
// in post execute of this class you can run a new thread of your downaloder thread. and in post execute of last thread you have to dismiss the progess bar.
new download activity.execute();
}
}
}
}
}
I have an activity that can show two different layouts. Both of the layouts are pre-defined (XML). Basically, if a condition is met, then layout A should be displayed. If the condition fails, then layout B should be displayed.
Layout A is a simplistic Linear Layout - it's my main "form", so to speak.
Layout B is a simplistic Relative Layout - it's a placeholder until some data can be downloaded. Once the data is downloaded (and a notification is sent), then I want to remove Layout B and display Layout A.
I've tried calling the invalidate() method on Layout B in the onResume() method of my Activity but that doesn't work.
I'm not sure what approach I should take, in (1) where to "correctly" switch the layouts, and (2) how I should go about displaying it. I'm assuming I need to inflate Layout A when my condition is met, but I'm not 100% sure about that.
Edit:
Snipped of my onCreate() method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutA); // will happen 99% of the time
...
if (!dbHelper.tableIsPopulated()) {
setContentView(R.layout.layoutB); // show placeholder bc no data exists
getData();
}
}
Unless you have a reason to not use a background Thread, I suggest using an AsyncTask and using a progress bar. It will be less costly than using a dummy Layout just as a placeholder until you get the data. And you said it won't be used but 1% of the time. Seems like a waste in my opinion
public class TalkToServer extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... params) {
//do your work here
return something;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// do something with data here-display it or send to mainactivity
}
You apparently know about AsyncTask but Here are the Docs for future visitors and it has an example of using the ProgressDialog.
Note
Since it isn't an inner class you will just need to pass your Context to the constructor of your AsyncTask if you are going to show your ProgressDialog from there.
I need to show standard loading circle on half-opaque background above current layout (with background and buttons etc). I found ProgressBar and how it works, but I need to render it on existing layout, and that's the problem.
To be more clear - imagine login screen with some image and button aka "Register". On click I need to show partly visible black background and a loading circle.
Try and see if this works (use it as an inner class)
private class executeHospitalNameGet extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(SettingsActivity.this);
private Context mContext;
public executeHospitalNameGet(Context context) {
mContext = context;
}
protected void onPreExecute() {
Dialog.setMessage("Getting Hospitals...");
Dialog.setTitle("Requesting Hospital Name");
Dialog.show();
}
protected Void doInBackground(String... urls) {
//DO WORK HERE
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
You would call it with this
new executeHospitalNameGet(getApplicationContext()).execute();
Use a RelativeLayout, It will allow you to have overlapping Views, check out this link:
http://developer.android.com/reference/android/widget/RelativeLayout.html
I think you're looking for something like modal dialog with loading animation...
check it out this... http://developer.android.com/guide/topics/ui/dialogs.html#ProgressDialog
I have create an android quiz application where i loaded all of question from web service. For this in oncreate method i wrote following
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.testlayoutforimage);
loadControls();
getPassingValue();
ParserMethod parserMethod=new ParserMethod();
//questionsObj=parserMethod.parseQuestionDetailsFor(passingFeature,numOfQuestion,passingSubject,passingChapter);
questionsObj=parserMethod.parseQuestionImages(passingSubject,passingFeature,passingChapter;
}
But problem is that when the question is loaded it take some time .
I want to add a progress bar. When the page is loaded then the progress is shown and the question is load . After that the bar is remove and Display the ques .how can i do this.
Using AsyncTask.. just like below.. code is not exactly right.. its just to give an idea..
classs backgrnd extends Asynctask{
protected object onPreExecute(){
//display dialog
}
protected object doInBackgroung(Object... arg){
//fetch data
}
protected object onPostExecute(Object result){
//dismiss dialog
}
}
You can Use AsyncTask class for this.The class is designed so that you can do something in the background.It has overridden method onPreExecute where you can show the ProgressDialog and on doInBackground method load your question.On preExecute method cancel the dialog and update your UI