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
Related
Here is the scenario that I am trying to resolve. I have a Layout which contains some data to be submitted to a server, this Activity layout needs to upload multiple files (Attachments) which are listed using RecyclerView.Adapter. In each attachment that is listed in bottom part of my layout is a progress bar that shows status or the percentage of the file that has been uploaded to the sever. On the click of the submit button, it calls an AsyncTask and in the onPostExecute method of this Activity layout I want to upload my attachments.
What is the best way to overcome this issue? Please help.
If your async task is an inner class of an activity or fragment, you can simply call a method that lives in the activity or fragment from within onPostExecute
class MyActivity extends Activity
{
public void showOrHideProgress(Result result)
{
// your code here
}
class MyAsyncTask extends AsyncTask
{
private final WeakReference><View> progressBarReference;
public MyAsyncTask(#NonNull View progress)
{
this.progressBarReference = new WeakReference<>(progress);
}
#Override
protected void onPostExecute(Result result)
{
super.onPostExecute(result);
showOrHideProgress(result); // or do something with progressBarReference
}
}
}
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 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 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?
I am having problem with setting a new Drawable to my ProgressBar.
If I use the setProgressDrawable() inside onCreate() method it works great. But when I try to call the same method inside a Handler post callback it doesn't work and the progressbar disapears.
Can someone explain this behaviour? How can I solve this problem?
downloadingBar.setProgress(0);
Drawable progressDrawable = getResources().getDrawable(R.drawable.download_progressbar_pause_bg);
progressDrawable.setBounds(downloadingBar.getProgressDrawable().getBounds());
downloadingBar.setProgressDrawable(progressDrawable);
downloadingBar.setProgress(mCurrentPercent);
First you should reset the progress to zero
Set the progress drawable bounds
Set new progress drawable
Set new progress
Bumped into this problem myself and I managed to get it working :)
I used the AsyncTask to handle the background tasks/threads, but the idea should be the same as using Runnable/Handler (though AsyncTask does feel nicer imo).
So, this is what I did... put setContentView(R.layout.my_screen); in the onPostExecute method! (ie. instead of the onCreate method)
So the code looks something like this:
public class MyScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.my_screen); !!! Don't setContentView here... (see bottom)
new MySpecialTask().execute();
}
private int somethingThatTakesALongTime() {
int result;
// blah blah blah
return result;
}
private void updateTheUiWithResult(int result) {
// Some code that changes the UI
// For exampe:
TextView myTextView = (TextView) findViewById(R.id.result_text);
myTextView.setText("Result is: " + result);
ProgressBar anyProgressBar = (ProgressBar) findViewById(R.id.custom_progressbar);
anyProgressBar.setProgressDrawable(res.getDrawable(R.drawable.progressbar_style));
anyProgressBar.setMax(100);
anyProgressBar.setProgress(result);
}
private class MySpecialTask extends AsyncTask<String, Void, Integer> {
ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(MyScreen.this, "", "Calculating...\nPlease wait...", true);
}
#Override
protected Integer doInBackground(String... strings) {
return somethingThatTakesALongTime();
}
#Override
protected void onPostExecute(Integer result) {
mProgressDialog.dismiss();
setContentView(R.layout.my_screen); // setContent view here... then it works...
updateTheUiWithResult(result);
}
}
}
To be honest, why you need to call setContentView in onPostExecute I have no idea... but doing so means you can set custom styles for your progress bars (and they don't disappear on you!)
Maybe you put the code in a thread which is not main thread.
If you want to work with the UI, you must do that in the main thread :)
I was also facing the same issue but in my case it is due to the use of Drawable.mutate() method. When i removed that method it started working fine. I also noticed that this issue exist below api level-21(lollipop).