My app loads a lot of stuff on startup and after testing it delays too long at the beginning to not have a splash screen. So, I want to display a splash screen until my app is done loading. I do NOT want to display a screen with a timer for X seconds. I found an example here:
Android SplashScreen
I tried implementing the code in the SO topic above but I just don't understand the code. After integrating it in my code I come up with one error that I commented into the code below. But I don't understand a lot of the code and I have commented in the code below the parts I am confused by.
public class MainMenu extends Activity {
private ProgressDialog pd = null;
private Object data = null; //What is this?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.mainmenu);
// show the ProgressDialog on this thread
this.pd = ProgressDialog.show(this, "Working...", "Downloading data...", true, false);
// start a new thread that will download all the data
new DownloadTask().execute("Any parameters to download."); //What is DownloadTask()?
}
private class DownloadTask extends AsyncTask<String, Void, Object> {
protected Object doInBackground(String... args) { //Are these parameters correct?
return "replace this with your object"; //What is this?
}
protected void onPostExecute(Object results) {
// pass the resulting data to the main activity
MainMenu.this.data = result; //Error: "result cannot be resolved to a variable"
if(MainMenu.this.pd != null) {
MainMenu.this.pd.dismiss();
}
}
}
}
Let's start with the error:
MainMenu.this.data = result;
Notice the typo? It should be result*s*:
MainMenu.this.data = results;
Addressing the rest of your questions below:
private class DownloadTask extends AsyncTask<String, Void, Object>
The declaration is for an inline class called DownloadTask, and it states that you'll be taking Strings (via String...) as parameters to your doInBackground(String... params).
The second parameter (Void in your case) indicates the datatype used to "publish" the progress via publishProgress(DATATYPE)/onProgressUpdate(DATATYPE... progress). This method is suitable for notifying the user of changes, for example when you've finished downloading a file but still have a few to go.
The last parameter (Object), indicates what type of data you'll be passing on to onPostExecute(DATATYPE), in this example Object. This could either be to update a ListAdapter somewhere, or trigger any other UI change based on the outcome of the actions done in doInBackground.
Show ProgressDialog in onPreexecute and dismiss it in onPostExcute methods
something like this
private class DownloadTask extends AsyncTask<String, Void, Object> {
#Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(activity);
mProgressDialog =ProgressDialog.show(activity, "", "Please Wait",true,false);
super.onPreExecute();
}
protected Object doInBackground(String... args) { //Are these parameters correct?
return "replace this with your object"; //What is this?
}
protected void onPostExecute(Object results) {
// pass the resulting data to the main activity
MainMenu.this.data = results; //it should be results
if (mProgressDialog != null || mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
if(MainMenu.this.pd != null) {
MainMenu.this.pd.dismiss();
}
}
Related
I'am trying to implement an AsyncTask in Android that will load all my data from the database. Therefore I used the onPreExecute method to start a ProgressDialog
public class DataLoader extends AsyncTask<Void, Void, Void> {
private LoginActivity activity;
private ProgressDialog nDialog;
public DataLoader (LoginActivity act){
this.activity = act;
nDialog = new ProgressDialog(activity);
}
protected void onPreExecute() {
System.out.print("Start AsyncTask");
nDialog.setMessage("Loading data..");
nDialog.setTitle("Starting the application");
nDialog.setIndeterminate(false);
nDialog.setCancelable(true);
nDialog.show();
}
#Override
protected Void doInBackground(Void ... params) {
System.out.println("Starting doInBackground");
loadDashboardData();
return null;
}
protected void onPostExecute() {
nDialog.dismiss();
Intent i = new Intent();
i.setClass(activity.getApplicationContext(), DashboardActivity.class);
activity.startActivity(i);
}
The I use the doInBackground method to load call a function to load the data. This method is called from an visible activity. The task is called with:
public class LoginActivity extends Activity {
public void onClick(View v) {
DataLoader dl = new DataLoader(this);
dl.execute();
}
}
And the code for the doInBackground is:
protected Void doInBackground(Void ... params) {
System.out.println("Starting doInBackground");
loadDashboardData();
return null;
}
Now the problem is that my doInBackground method will not finish. I tried to implement the loadDashboardData() call in the onPreExecute method. This will not show my dialog box but it will load the data correctly. In this case the UI Thread is not responding and will response after all the data has been loaded.
What can hinder the doInBackground method to execute correctly and load the data properly? The called method works (because I can call it and get the correct data). Also I'am not seeing the println in my run console.
In the frontend I can see the progressbar spinning, but in the backend I can see that no data is loaded.
Your problem is that you are overriding the wrong method name : )
It should be
#Override
protected void onPostExecute(Void result) {
// your code
}
as in your case the variable which doInBackground return is Void.
You can check the documentation about AsyncTask .
hi i have AsyncTask in my app but i am unable to change its setMessage
for example :-
private class ProgressTask1 extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog;
public ProgressTask1(MainActivity mainActivity) {
context = mainActivity;
dialog = new ProgressDialog(context);
}
private Context context;
protected void onPreExecute() {
this.dialog.setMessage("Checking system...");
this.dialog.setCancelable(false);
this.dialog.setTitle("Please Wait...");
this.dialog.setIcon(R.drawable.ic_launcher);
this.dialog.show();
}
now i want that setmessage to change i tried adding it in doinbackground
protected Boolean doInBackground(final String... args) {
dothis1();
this.dialog.setMessage("one done...");
dothis2();
this.dialog.setMessage("two done...");
but this is making app force close and do not rate it low because i tried my best and searched forum but could able to fix this so asked for hand at this nice community :)
anybody can help ? :)
ERROR
05-13 23:36:34.899: E/AndroidRuntime(2454): Caused by:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
ohmm, you should not update UI from background thread. To update UI, you can do by two ways:
1) Using publishProgress (Progress... values) and onProgressUpdate(...). To do that, you must change your AsynTask class:
private class ProgressTask1 extends AsyncTask<String, String, Boolean> {
//.......... //your init
#Override
protected Boolean doInBackground(String... params) {
//your background handle
//publish to change UI
String toShow = "your_string_here";
publishProgress(toShow);
//return ...; //your return value
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//detect message and show it.
//this.dialog.setMessage(values[0]);
}
}
2) Using onPostExecute(....):
private class ProgressTask1 extends AsyncTask<String, Void, Boolean> {
//.......... //your init
#Override
protected Boolean doInBackground(String... params) {
//your background handle
//return ...;//your return value
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
String toShow = "your_string_here";
//this.dialog.setMessage(toShow);
}
}
You cannot update the UI from the background.
See AsyncTask.onProgressUpdate to update the UI based on your background progress. :D
So I'm just trying to create an Alert Dialog that is just a message (no buttons or titles). I want to display an alert dialog when a background task is running. The alert dialog will run on the UI thread.
Here's what I have done so far:
protected void onPreExecute() {
super.onPreExecute();
AlertDialog altDlg;
altDlg = new AlertDialog.Builder(AlertDialogActivity.this).create();
altDlg.setMessage("Retrieving Information. Please Wait");
altDlg.show();
}
I also tried doing this:
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setMessage("Retrieve Info. Please Wait").show();
The error I am getting with the first one is:
cannot find symbol 'AlertDialogActivity'
symbol: class AlertDialogActivity
location: class com.example.Device.Activity
The second attempt error says:
incompatible types: com.example.Device.Activity cannot be converted to android.content.Context
I'm not sure what I am doing wrong in either scenario. I just want to display a basic message when a background task is running and I was hoping the closest thing I can use is AlertDialog.
EDIT for how to set up AsyncTask properly:
Small background of what I want to do. I just want to read in a file, deserialize it and save it's contents to a db.
Right now I'm assuming I only need two activities.
One is my main activity:
public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
final Button setup_button = (Button) findViewById(R.id.setup_button);
setup_button.setOnClickListener (new View.OnClickListener() {
public void onClick(View view){
setContentView(R.layout.retrieve_info);
}
});
}
}
Now the onClick event just moves to the new view that is supposed to display the message or alert dialog that says retrieving information. Please Wait. It displays the message while reading a file and saving to db. Once the file is read and saved, The message should disappear and say something like setup complete.
My second activity so far is:
public class RetrieveInfoActivity extends AsyncTask<Void,Void,Void> {
private ProgressDialog progressBar;
private void retrieveInfo(String fileName) {
try {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
//Read all the lines until there are no more lines
while (scanner.hasNextLine()) {
scanner.nextLine();
//TODO: deserialize and save to db
}
scanner.close();
}
catch (FileNotFoundException e) { e.printStackTrace(); }
}
#Override
protected Void doInBackground(Void... params) {
retrieveInfo("test.txt");
return null;
}
protected void onPreExecute() {
super.onPreExecute();
progressBar.setIndeterminate(true);
progressBar.setCancelable(false);
progressBar.setMessage("Retrieve Information.Please wait");
progressBar.show();
}
#Override
protected void onPostExecute() {
progressBar.dismiss();
}
}
That's all I really have so far. I just need to understand how to set up this in Android conceptually.
Hope this makes sense.
Try this:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Instead of using an AlertDialog use a ProgressBar, it will do the trick for you.
private ProgressDialog progressBar;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setIndeterminate(true);
progressBar.setCancelable(false);
progressBar.setMessage("Your message");
progressBar.show();
}
#Override
protected void onPostExecute(final String error_code) {
progressBar.dismiss();
}
Looks like you are extending AsyncTask and trying to use it as a context. That won't work as AsyncTask itself is nothing but an abstract class.
You need to create a custom constructor for your AsyncTask to fetch the Context:
public class MyTask extends AsyncTask<Void, Void, Void> {
private Context mCtx;
public MyTask(Context context) {
mCtx = context;
}
...
Then when starting your AsyncTask, pass the context:
new MyTask(this).execute();
Another way would be to make the AsyncTask an inner class and use YourActivity.this when creating the dialog. Example:
public class YourActivity extends Activity {
...
private class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
AlertDialog dialog = new AlertDialog.Builder(YourActivity.this).create();
}
#Override
protected Void doInBackground(Void... params) {
...
}
}
}
I am encountering a problem in my Android application. I am creating a currency converter. I need to create a progressdialog that appears when you convert a value from one currency to another.
Here is part of my code:
if (text1.equals("US Dollar - USD") && text2.equals("Euro - EUR") && edittextdollars.length() > 0 && edittexteuros.length()==0) {
dialog1 = ProgressDialog.show(getActivity(), "", "Calculating...");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try{
convertvalues("USD", "EUR");
handler.sendEmptyMessage(0);
}
catch (Exception e) {
edittexteuros.setText("Error");
}
}
});
thread.start();
}
private Handler handler = new Handler () {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
dialog1.dismiss();
break;
}
}
};
The progressdialog comes up and goes away, but nothing happens in the background. Here are a few pics of what my app looks like:
This is before the progressdialog comes.
When I press calculate:
After the progressdialog finishes:
As you can see, after the progressdialog goes away, my values don't convert.
In my code,
convertvalues("USD", "EUR");
just gets actual currency value from the internet and multiplies it with the value in my edittext. There is nothing wrong with it and it worked without the progressdialog. I have tested it many times myself.
What am I doing wrong here? I have checked Google for over a week, but I could not find a single solution. Any help regarding this problem is greatly appreciated.
Just like how you update your progressdialog in a handler, you must also update EditTexts in the handler (as it must run on the UI thread). So ideally you would return the result from convertvalues and then pass it to the handler via a message.
From what I can see, your code is fine but you aren't updating the TextView/EditText values when you dismiss the dialog. This means that although it looks like nothing is happening, it actually is - you just aren't updating to see the results.
So, assuming convertvalues() has the converted values stored somewhere, before you call dismiss() you should set your TextViews based on those values.
you can use asynctask in android
see following code may be it will help you..
private class asyncTask extends AsyncTask<Void, Void, Boolean>
{
Context context;
ProgressDialog pd;
asyncTask(Context context)
{
this.context = context;
pd = new ProgressDialog(activityContext);
}
protected void onPreExecute()
{
pd.setTitle("Loading..");
pd.setMessage("Please wait ...");
pd.setCancelable(false);
pd.show();
}
protected void onPostExecute(Boolean result)
{
if(pd.isShowing()) pd.dismiss();
}
#Override
protected Boolean doInBackground(Void... params)
{
convertvalues();
return boolean_value;
}
}
And Just Call this asynctask with
new asyncTask(Your_Context).execute();
I recently needed to use AsyncTask in an activity in my android app. So I made a class inside the activity and extended AsyncTask in that class.
But now, whenever I launch that particular activity, my app immediately crashes. I tried putting the whole onCreate() of the activity in a try, catch block, but no exceptions were raised. The app just crashes immediately when I launch that activity, without any explanation in the LogCat.
This started happening after I added the AsyncTask class mentioned above. Also, the AsyncTask part is NOT executed when the activity is launched, it executes on pressing a button. What could be going wrong? I have added the relevant code below:
public class ListViewA extends Activity{
public void onCreate(Bundle savedInstanceState) {try{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv= (ListView)findViewById(R.id.listview);
//computation
}
private String[] top() {
new RetreiveFeedTask().execute(ctr,ctz);
return er;
}
public class RetreiveFeedTask extends AsyncTask<Context, Void, String[]> {
String[] q;
protected String[] doInBackground(Context... params) {
//computation
}
protected void onPostExecute() {
er=q;
gff=true;
}
}
EDIT:
I found an error in LogCat which looks important:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.exampleapp/com.example.exampleapp.ListViewA}: java.lang.NullPointerException
Your edit is interesting and suggests that there is a problem in the instantiation of the Activity, in which case I would look at the variable declarations quite carefully. However, in the absence of any of that code (or more onCreate code), or the surrounding lines from the logcat, it's hard to be more specific.
As #Raghunandan says, the way your AsynTask is constructed is incorrect, it should be something like:
public class RetreiveFeedTask extends AsyncTask<Context, Void, String[]> {
String[] q;
#Override
protected String[] doInBackground(Context... params) {
//computation
return result; // result is of type String[]
}
protected void onPostExecute(String[] result) {
// do something with result ...
er=q;
gff=true;
}
}
A secondary point is your top() function, which returns er. I am guessing that you want it to wait until the AsyncTask is complete and then return er, which has been calculated by the AsyncTask. However, what it will do at present is to set the AsyncTask and then immediately return er: it won't wait for the AsyncTask to complete.
To achieve that, you probably need to split the button press action into two phases:
Create and run the AsyncTask
OnPostExecute in the AsyncTask calls the code which currently uses the er returned by top.
public class ListViewA extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv= (ListView)findViewById(R.id.listview);
//computation
new RetreiveFeedTask().execute(ctr,ctz);
}
...
public class RetreiveFeedTask extends AsyncTask<Context, Void, String[]>{
#Override
protected String[] doInBackground(Context... fileName) {
//computation
String[] q;
//Know that fileName is an Array
return q
}
protected void onPostExecute(String[] result) {
//do something with the result
}
}
...
}
I have a private class ReadFilesTask extends AsyncTask<String, Void, String> in my program. Under that, I have: protected void onPreExecute(),
protected String doInBackground(String... params), and
protected Void onPostExecute(String result).
The first two have #Override above them. The only one I'm ACTUALLY using though, is doInBackground. I'd first really just try adding #Override to doInBackground(). Next, try changing Context to String.
EDIT:
You are also missing the function to grab an activity. Again, this is simply what I'm doing in my code and a few examples I saw online:
public RetreiveFeedTask(Activity activity) {
this.activity = activity;
}
Something like that.