In my android app, I have to load the data on first run through online server. But after splash screen, the loading bar should be displayed with black background. But when I am doing, it shows the content behind the progress bar. what i want is just to display the progress bar (with black background) until the data gets downloaded.
Here is my code of mainactivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
task myTask = new task();
myTask.execute();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//other code
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class task extends AsyncTask<String, Integer, String> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog=new ProgressDialog(MainActivity.this, android.R.style.Theme_Translucent_NoTitleBar);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(20000);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(progressDialog!=null)
progressDialog.dismiss();
}
}
}
Well, while copy-pasting some of the brackets may be gone wrong.
But be assured the code is running fine, The problem comes that background is loaded alongwith the loading screen. I got to know about get() method to stop the process being loaded. But this also stopped the view of loading bar.
Please help. Or any alternative way suggestions?
Remove setContentView() from onCreate() and place it in onPostExecute() at the end.
Related
I have a catch 22 here. If I use a AsyncTask to run my network activity I can't update my user interface from that thread.
MainActivity.onCreate(...){
myAsyncTask.execute();
//E/AndroidRuntime(1177): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
}
The Network activity will be continuous and needs to happen on a different thread. So, I turned to super.runOnUiThread to fix the error above and because it accepts Runnable as its parameter. Unfortunatly, the Javadocs are not clear in that I don't know if super.runOnUiThread is going to make a Thread or just call run directly. Apparently it does not make a Thread, because I get this exception: android.os.NetworkOnMainThreadException
Given that I have a one-screen App that need a connection. What is the simplest way to make this work?
If I use a AsyncTask to run my network activity I can't update my user interface from that thread
That is why AsyncTask has onPostExecute(). Put your UI update logic in there (or onProgressUpdate(), if you wish to update the UI as the background work is going on).
As CommonsWare said you can use onProgressUpdate() to update your UI .Here is an example, I used it to make a cool splash screen.
https://www.dropbox.com/s/cyz7112k4m1booh/1.png
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
bar=(ProgressBar) findViewById(R.id.progressBar);
new PrefetchData().execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.splash, menu);
return true;
}
private class PrefetchData extends AsyncTask<String,String,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// before making http calls
}
#Override
protected String doInBackground(String... arg0) {
Random ran=new Random();
int count;
int total=0;
try {
while(total <= 100){
count=ran.nextInt(30);
total+=count;
Thread.sleep(1000);
if (total >= 100) publishProgress(""+100);
//here publishProgress() will invoke onProgressUpdate() automatically .
else publishProgress(""+(int) total);
}
}catch (InterruptedException e) {
e.printStackTrace();
Log.e("Error:",e.getMessage());
}
return null;
}
protected void onProgressUpdate(String... progress) {
bar.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Intent i = new Intent(SplashActivity.this, MainActivity.class);
startActivity(i);
finish();
}
}
I seem to be going round in circles.
I have some code that even on a Galaxy S3 takes a few seconds to run. Drags data from database.
I want to add a progress bar popup (spinning circle) around this to give the user that the app is doing something.
I have tried Asyntasks elsewhere in app and work fine but for this type the main UI is not waiting for the Asyntask to finish before moving on and so the new activity that is called does not have all the data it needs and crashes.
Is AsyncTask the best way round this or is there an easier way to Puase the main Activity, show a progress bar and then move on once the long deley has been completed.
Thanks for time
UPDATE
public class UpdateDetailsAsyncTask extends AsyncTask<Void, Void, Boolean> {
private Context context;
private TaskCallback callback;
private ArrayList<Object> object;
private ProgressDialog progress;
public UpdateDetailsAsyncTask (
Context pContext,
ArrayList<Object> pObject,
TaskCallback pCallback) {
context = pContext;
callback = pCallback;
object = pObject;
}
#Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecuted");
progress = new ProgressDialog(context);
progress.setMessage(context.getResources().getString(R.string.loading));
progress.show();
}
#Override
protected Boolean doInBackground(Void... params) {
Log.i("Archery", "AsyncTask Excuted");
Log.i("Archery Scorepad", "Building Continue Round Details");
// Save Data to Database
return true;
}
protected void onPostExecute(Boolean result) {
Log.i("AsyncTask", "onPostExuted");
progress.dismiss();
callback.startNewActivity();
}
}
Task is called from main Activity
new UpdateDetailsAsyncTask(this, ArrayListOfObjects, this).exute();
UPDATE 2
..
UPDATE 3
The Code that does some work calls an a method within a Util Class which in calls a database class. I have log messages showing for all the rows of data I am saving to the database. It starts correctly and runs through it but the onPostExecute() appears to be called before the database method has completed.
Is my issue that I have nested classes within the activity and the task appears to have completed when the class below it has not?
Thanks
You must change to the next activity in onPostExecute from Asyntask
Yes!
Here is a simple code of AsuncTask
private class LoadImageAction extends AsyncTask<String, String, String>{
private Course course;
private ProgressBar pb;
public LoadImageAction(Course course, ProgressBar pb){
this.course = course;
this.pb = pb;
}
#Override
protected void onPreExecute(){
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
protected void onProgressUpdate(String... string){
}
#Override
protected void onPostExecute(String result){
}
}
You can run the action by
new LoadImageAction().execute();
For a few days a have some problem.
I need to show simple ProgressBar (not dialog) while doing some stuff in main thread...
I thought its a very simple question, but i cant do this, help me please.
First i tried simple setVisibility(View.VISIBLE) before and setVisibility(View.GONE) after.
But this is doing in the same thread, and ProgressBar freezed while my function working.
Now i have this code, but i have some error, and i dont know whats wrong..
my simple layout :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
i have a base activity :
public class BaseActivity extends Activity {
public ProgressBar loading;
public class ProgressBarShow extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... unused) {
return(null);
}
protected void onProgressUpdate() {
}
protected void onPreExecute() {
loading.setVisibility(View.VISIBLE);
}
protected void onPostExecute() {
}
}
}
and finally my working activity , which extends BaseActivity
public class SearchActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loading = (ProgressBar) findViewById(R.id.loading);
new ProgressBarShow().execute();
//doing long stuff
//new ProgressBarHide().execute(); there isnt, but sense the same
}
}
I have many activities, which need progress bar, thats why i have created BaseActivity,
to not to dublicate code.
I need to do long work (stuff function) in main thread, because i want to freeze main window and not to allow user do anything (click button etc..), just show working ProgressBar.
Whats wrong in my example? Or give me some advice how can i do this better
class ProgressTask extends AsyncTask<Integer, Integer, Void>{
ProgressBar progress;
Context context;
public ProgressTask(ProgressBar progress, Context context) {
this.progress = progress;
this.context = context;
}
#Override
protected void onPreExecute() {
// initialize the progress bar
// set maximum progress to 100.
progress.setMax(100);
}
#Override
protected Void doInBackground(Integer... params) {
// get the initial starting value
int start=params[0];
// increment the progress
for(int i=start;i<=100;i+=5){
try {
boolean cancelled=isCancelled();
//if async task is not cancelled, update the progress
if(!cancelled){
publishProgress(i);
SystemClock.sleep(1000);
}
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
return null;
}
//Has direct connection to UI Main thread
//Called everytime publishProgress(int) is called in doInBackground
#Override
protected void onProgressUpdate(Integer... values) {
progress.setProgress(values[0]);
Toast.makeText(context, "test"+values[0], Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(Void result) {
// async task finished
Log.v("Progress", "Finished");
}
#Override
protected void onCancelled() {
progress.setMax(0);
}
}
Use AsyncTask http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html Put your ProgressBar in it, while all work is doing in main thread
I am working on an android app, in that app i have intent2 which on click redirects to intent3 and takes some time then loads a table and displays server data into it.
Sometimes if there is a lot of data, it tales pretty much time to get the dataload and the time blank screen is displayed increases.
i wish to show a loading bar till the data loads.
how can i show the ProgrssBar till only when data is not displayed ?
Probably your best bet would be to use AsyncTask in your "intent3":
You could do it like this:
private class performBackgroundTask extends AsyncTask <Void, Void, Void>
{
private ProgressDialog Dialog = new ProgressDialog(ClassName.this);
protected void onPreExecute()
{
Dialog.setMessage("Please wait...");
Dialog.show();
}
protected void onPostExecute(Void unused)
{
try
{
if(Dialog.isShowing())
{
Dialog.dismiss();
}
// do your Display and data setting operation here
}
catch(Exception e)
{
}
#Override
protected Void doInBackground(Void... params)
{
// Do your background data fetching here
return null;
}
}
You probably need to run an AsyncTask on onCreate when you open the new activity, the structure of the asynctask would be like this (taken from the google doc), notice that if you want to increament a progress bar you have to implement onProgressUpdate and call publishProgress in the doInBackground method
private class DownloadFilesTask extends AsyncTask<Void, Integer, Void> {
protected void onPreExecute()
{
// show your progress bar
}
protected Void doInBackground(Void... params) {
// do your work and publish the progress
publishProgress(progress);
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Void result) {
//dismiss your progress bar
}
}
This code is just an example, of course you need to adapt it to your logic/code.
Check out this simple and complete example
I am facing the issue with displaying progressbar onItem selected in option menu.
My code is here:
case R.id.mnuLogout:
showDialog(Constants.PROGRESS_DIALOG);
closeOptionsMenu();
if(MyApp.IsLoggedOut())
handler.sendEmptyMessage(Constants.LOGOUT);
else
handler.sendEmptyMessage(Constants.ERROR_MSG);
Progressbar is displayed after completion of IsLogged method.
You're calling get() right after the AsyncTask as executed and lose asynchronous behavior because this method waits until task is finished. You should add all the code in try/catch block to AsyncTask.onPostExecute() method and also dismiss the dialog from this method.
void doLogout() {
new LogoutTask().execute();
}
void dispatchLogoutFinished() {
dismissDialog(Constants.PROGRESS_DIALOG);
if (MyApp.IsLoggedOut()) {
// do something
} else {
// do something else
}
}
private class LogoutTask extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
TheActivity.this.showDialog(Constants.PROGRESS_DIALOG);
}
protected Void doInBackground(Void... params) {
return null;
}
protected void onPostExecute(Long result) {
TheActivity.this.dispatchLogoutFinished();
}
}
And I don't think you need to send messages to the handler. The dispatchLogoutFinished() is executed on the UI thread, so there's no need for synchronization.