I develop one application in Android. Which contains so many data (String) and images. string data are come from database and images comes from /res folder.
In My Application First Activity shows categories of books. Then i select any one of them then jump to the next activity which display all books images and brief description of selected category these all data are coming from database with Query operation and fill custom list view with ArrayAdapter. These is working and display all the things which i want.
but the problem is that when i click on category from one activity it takes more than 1 minute time to display second activity (Detail Information of Selected Category). So, Here user is stuck. It is bad for my application.
So is there any way to solve these or any Idea to display Activity Loading Process between One Activity to Second Activity ?
Thanks in Advance.
Please Help Me to solve these.
use AsyncTask as
public class My_Game_Task extends AsyncTask<String, Void, Void> {
#Override
protected void onPreExecute() {
//put a preloder
super.onPreExecute();
}
#Override
protected Void doInBackground(String... arg0) {
// TODO Auto-generated method stub
find data from database
return null;
}
#Override
protected void onPostExecute(Void result) {
dismiss preloader
set adapter here
super.onPostExecute(result);
}
}
call on
oncreate as new My_Game_Task().execute();
this will immediately show the next activity and will show a preloader
First of all where are you testing the app.. if its on emulator then check it on actual device you would get a idea how much delay takes place actually.!
I had similar problem it takes minutes on emulator but runs amazingly on actual device.It takes just 1 second to display..
Try this one it will make a delay of one second before going to execute any other operations,
try {
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
Related
On my android app, I use the Parse.com online database to store my data. In the onCreate() method of my activity, I use the method findInBackground() to asynchronously load data.
The findInBackground() method does not initially reconnect to the activity and continue to run forever. However, if I click on the home button of my phone and then re-load the app, the findInBackGround() method finally reconnects and load the data.
I would like to:
make the findInBackground() method reconnect with the activity without needing to reload the app
show a loading image (animated gif ?) while data is loading.
Would you guys have any advice on my problem ?
Thank you in advance for your help,
Alex
PS: I already tried the find() method of parse. Even if it reconnects automatically with the app, I don't think it's the right way to proceed since it blocks the UI of the caller activity until data is loaded.
==================================================================================
I finally found the answers to my questions:
I put the code to populate the listView INSIDE a method of the findCallBack class. Thus, I make sure I will use the result of the findInBackground() method only AFTER it has finished run. Previously, I had put the code to populate the listView OUTSIDE of the findCallBack class, so even if it came after in my code, it was actually executed before the end of findInBackground(), so didn't work.
For the loading image, I used an answer found on this site, which consists in activitating and stopping a ProgressDialog at the appropriate time (before and after findInBackground()).
startLoading(); //Show the loading image
query.findInBackground(new FindCallback() {
public void done(List<ParseObject> allQuestionsVal, ParseException e) {
if (e == null) {
for(int i = 0; i<=allQuestionsVal.size()-1;i++){
ParseObject questionVal = allQuestionsVal.get(i);
Question question = new Question(questionVal.getObjectId(),
questionVal.getString("FIELD1"),
questionVal.getString("FIELD2"),
allQuestions.add(question);
}
stopLoading(); //Remove the loading image
//Use the result of the Query (allQuestions) to populate listVIew
ListView list = (ListView) findViewById(R.id.all_questions);
AllQuestionsAdapter adapter=new AllQuestionsAdapter(AllQuestions.this, allQuestions);
list.setAdapter(adapter);
}
else {
stopLoading(); //Remove the loading image
}
}
});
protected ProgressDialog proDialog;
protected void startLoading() {
proDialog = new ProgressDialog(this);
proDialog.setMessage("loading...");
proDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
proDialog.setCancelable(false);
proDialog.show();
}
protected void stopLoading() {
proDialog.dismiss();
proDialog = null;
}
PS: any comments are welcomed :)
I'm having a problem refresh the data in list view.
I get the data in the list from a server, and when I want to refresh the data I need to go to the server and receive the new data.
the notifyDataSetChanged() not helping and also the ListView.invalidateViews not helping.
when I rotate the device the list updated.
how can I load the list view in the same way the screen rotation do it?
This is the code on create that fill the list view.
thanks in advance.
query = new ParseQuery(PET_CLASS_NAME);
petListView.addHeaderView((View)getLayoutInflater().inflate(R.layout.header_row, null));
petDetailIntent = new Intent(getApplicationContext(), PetDetailActivity.class);
selectCityIntent = new Intent(this, CitiesActivity.class);
loadingIntent = new Intent(getApplicationContext(), LoadingActivity.class);
startActivityForResult(loadingIntent, LOADING_INTENT_CODE);
/*the user see list of pets that are still missing*/
query.whereEqualTo(PET_FOUNDED, false);
selectedCity = settings.getString("cityQuery", "");
if(selectedCity != ""){
query.whereEqualTo(PET_CITY, selectedCity);
}
query.findInBackground(new FindCallback() {
#Override
public void done(List<ParseObject> list, ParseException e) {
if (e == null) { //objects retrieved well
petList.addAll(list);
//MyAdapter
adapter = new MyAdapter(
getApplicationContext(),
android.R.layout.simple_list_item_1,
R.id.tv_pet_name,
petList);
setListAdapter(adapter);
}
else{
toaster(getResources().getString(R.string.error_message_load_pets));
finish();
}
finishActivity(LOADING_INTENT_CODE);
}
});
Use a AsyncTask for loadData from Server. It will load it faster.
Try this out:
private class YourTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... s) {
//Here you have to make the loading / parsing tasks
//Don't call any UI actions here. For example a Toast.show() this will couse Exceptions
// UI stuff you have to make in onPostExecute method
}
#Override
protected void onPreExecute() {
// This method will called during doInBackground is in process
// Here you can for example show a ProgressDialog
}
#Override
protected void onPostExecute(Long result) {
// onPostExecute is called when doInBackground finished
**// Here you can for example fill your Listview with the content loaded in doInBackground method**
}
}
And than you just have to call this AsyncTask always if you loading content from your server:
new YourTask().execute("");
Try it out!.. Hope this helps..
When you rotate the device, the activity is actually started stopped and started and your initial request will be made again.
You should place your request code into a method and recall it yourself
Similar to what Rawkode mentioned, it doesn't seem like the code that actually does the work of retrieving data from the server is reusable (since it lives in onCreate()). Take a look at this diagram: http://developer.android.com/images/activity_lifecycle.png. As you can can see, the onCreate() method only gets executed once, unless the Activity is re-created (i.e. rotating screen).
Also, from the given code, there doesn't seem to be evidence of a refresh method either. How will users be able to refresh the data? Consider refactoring your code such that the work is done in a method that you can call later on (i.e. refreshData()) and then figure out a way in which you would like your users to refresh. For example, you can use either the ActionBar with a refresh ActionItem, or a menu option or even a button.
I have four Tab at the top of my apps
The content of the fourth tab is that it will get data from sql server and then display in listview
since the amount of data retrieved is quite big, it takes 2-3 sec
The problem is that:
After I click the fourth tab, it has no response, then after 2-3sec, it displays the content
As I know it is loading the data from database, I will not continue to click
However, when users click it and no response, he may click and click and click
How to show something to user so that they know it is loading data??
You should use a CrusorLoader. This will display a loading circle while still making the UI active. Note that even if you're using lower versions of the android API, you can still access the CursorLoader class via the Android Support Package. For more information on loaders, checkout
new SomeTask(0).execute(); // write this line in your 4th tab onCreate()
/** Inner class for implementing progress bar before fetching data **/
private class SomeTask extends AsyncTask<Void, Void, Integer>
{
private ProgressDialog Dialog = new ProgressDialog(yourActivityClass.this);
#Override
protected void onPreExecute()
{
Dialog.setMessage("loading...");
Dialog.show();
}
#Override
protected Integer doInBackground(Void... params)
{
//Task for doing something
// get data from sql server and then display in listview
return 0;
}
#Override
protected void onPostExecute(Integer result)
{
if(result==0)
{
//do some thing if your list completed
}
// after completed finished the progressbar
Dialog.dismiss();
}
}
When a long-running process is started, you'll want to indicate that something is happening so the user knows to wait. You want a progress dialog.
Here is an example:
http://www.androidpeople.com/android-progress-dialog-example
I have an activity in which I display an image that is stored on a website.
I am using the following code to get it from its url and display the activity :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
setContentView(R.layout.ad_screen);
AsyncTask<String, Void, Integer> task = new AsyncTask<String, Void, Integer>()
{
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
#Override
protected Integer doInBackground(String... urls)
{
fetchAd();
return 0;
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
#Override
protected void onPostExecute(Integer result)
{
displayAd();
}
};
task.execute("");
}
That works very fine, but the behaviour is not the one I want : in this case, the activity is pushed on the screen (with a right to left animation) and then the AsyncTask begins. So the image is displayed on screen after a delay (which is normal).
But I would like to perform the request before the activity is pushed, so that the screen is displayed directly with its image without any delay.
Is there a way to have this behaviour ?
Thanks in advance.
You can download the image in the previous activity, create a bitmap, then pass it as an extra in the intent that launches this activity.
Use AsyncTask to load images in previous activity, and display the images in the current activity.
You could in the "parent" activity, the one that starts the new activity, do the fetching of the content, store it either in memory or some sort of fast access persistence, and after that start the activity.
Same principle could be to introduce a "loader" activity which would show a loader, and prefetch the data, when all data received it would start the activity that should display the data.
I'm displaying some data by using SQLite. When I click on one button data come from database. It takes some time. At that time the screen is black. At that time I want to display the rotating spinner before the data dispay. Any ideas?
Android provides a ProgressDialog for accomplishing what you want.
First i would like to suggest to have a look at AsyncTask page, so that you will come to know about the AsyncTask exactly.
Now, Implement AsyncTask as given below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new performBackgroundTask().execute();
}
private class performBackgroundTask extends AsyncTask <Void, Void, Void>
{
private ProgressDialog Dialog = new ProgressDialog(main.this);
protected void onPreExecute()
{
Dialog.setMessage(getString("Please wait..."));
Dialog.show();
}
protected void onPostExecute(Void unused)
{
Dialog.dismiss();
// displaying all the fetched data
}
#Override
protected Void doInBackground(Void... params)
{
// implement long-running task here i.e. select query/fetch data from table
// fetch data from SQLite table/database
return null;
}
}
Enjoy !!!
You should not execute long running tasks in UI thread as this blocks the UI redraw and makes app look unresponsive.
Use AsyncTask to execute long running tasks in background, while still updating the screen.
You can look at the standard music picker as one example of how to do this:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java
In addition to the whole "queries must be done off the main UI thread," this shows an indeterminant progress while first loading its data, fading to the list once the data is available. The function to start the query is here:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java#581
And to do the switch is here:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java#569
The layout has the list view put in a frame layout with another container holding the progress indicator and label. The visibility of these is changed to control whether the list or progress indicator are shown:
https://android.googlesource.com/platform/packages/apps/Music/+/master/res/layout/music_picker.xml