Task and Back Stack http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
Activity and Task Design Guidelines http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html
xxx
Classes
Loader & LoaderManager (Ref: http://developer.android.com/guide/topics/fundamentals/loaders.html) Make it easy to asynchronously load data
in an activity or fragment.
Configuration Chagned By default, Android system will restart Activity when configuration changed, such as locale, orientation, etc.
If you want to process such events by yourself, just define android:configChanges in Android Menifest, and implement interface onConfigurationChanged. ( NOTE: 1, from Android 3.x, you must set in AndroidManifest.xml, otherwise, even if you set android:configChanges, the method onConfigurationChanged won't be invoked, and Activity still will be recreated. 2, If you want view to handle configuration changes event itself, you can define a subclass of the view, and override the method onConfigurationChanged )
If you want Android system to process configuration changed event by default, while you need to get konwn once configuration changed, just implement onRetainNonConfiguratoinInstance and return some value, this function will be called by Android system when configuration changed, and you can get its result by invoking getLastNonConfiguratonInstance to check if configuration has changed, i.e public void onRetainNonConfiguratoinInstance() { //Generally, in this way to save a lot of or complicated data; otherwise, you can save to Bundle in onSaveInstanceState/onPause
/* While you can return any object, you should never pass an object that is tied to the Activity, such as a Drawable, an Adapter, a View or any other object that's associated with a Context. If you do, it will leak all the Views and resources of the original Activity instance. (To leak the resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.) */ return true; }
.... //Generally, you need to call getLastNonConfiguratonInstance to restore data in onCreate() Object b = getLastNonConfiguratonInstance(); if (b != null && b) { //Configuration changed }
public void onConfigurationChanged(Configuration newConfig)
{ //When this method is invoked, Resources object is already updated, so here you can reset any appropriate resource for the new configuration is used, such as reset ImageViews with setImageResource(int), or string items. if(!m_curConfig.locale.equal(newConfig.locale)) //locale changed { m_txtView.setText(R.string.xxx); //reset text }
The best way to handle a configuration change The best way to handle a configuration change, such as a change in the screen orientation, is to simply preserve the state of your application using onSaveInstanceState() and onCreate()/onRestoreInstanceState(), as discussed in the previous section. (Refer to: http://developer.android.com/guide/topics/fundamentals/activities.html)
Furthermore, onSaveInstanceState and onCreate/onRestoreInstanceState is not guaranteed to be invoked in pair, for example, when screen is off, onSaveInstanceState is invoked, but onCreate/onRestoreInstanceState will not be invoked.
xxx
onSaveInstanceState() The system calls this method before making the activity vulnerable to being destroyed and passes it a Bundle object.
There's no guarantee that onSaveInstanceState() will be called before your activity is destroyed, because there are cases in which it won't be necessary to save the state (such as when the user leaves your activity using the BACK key, because the user is explicitly closing the activity). If the method is called, it is always called before onStop() and possibly before onPause(). Because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity.
However, even if you do nothing and do not implement onSaveInstanceState(), some of the activity state is restored by the Activity class's default implementation of onSaveInstanceState(). Specifically, the default implementation calls onSaveInstanceState() for every View in the layout, which allows each view to provide information about itself that should be saved.
Although the default implementation of onSaveInstanceState() saves useful information about your activity's UI, you still might need to override it to save additional information. If you override the method in order to save additional state information, you should always call the superclass implementation of onSaveInstanceState() before doing any work.
(Refer to: http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState)
xxx
ExpandableListActivity An activity that displays an expandable list of items by binding to a data source implementing the ExpandableListAdapter, and exposes event handlers when the user selects an item. ExpandableListActivity hosts a ExpandableListView.
TabActivity
ListActivity An activity that displays a list of items. ListActivity hosts a ListView object.
LauncherActivity Displays a list of all activities which can be performed for a given intent.
PreferenceActivity
NativeActivity An activity that will be implemented
purely in native code. (You can find such sample native-activity under \samples\native-activity\)
xxx
FAQ
What's Activity An Activity is an application component that provides a screen with which users can interact in order to do something. Each activity is given a window in which to draw its user interface. The window typically fills the screen, but may be smaller than the screen and float on top of other windows.
LifeCycle - Paused Another activity is in the foreground and has focus, but this one is still visible. That is, another activity is visible on top of this one and that activity is partially transparent or doesn't cover the entire screen.
- Stopped The activity is completely obscured by another activity (the activity is now in the "background"). It is no longer visible to the user and it can be killed by the system when memory is needed elsewhere.
How to use preference objects in TabActivity Create a class CX extended from PreferenceAcvitity Add the activity declaration of CX in AndroidManifest.xml In TabActivity subclass, use following code to create tab TabHost tabHost = getTabHost(); Intent intent = new Intent(this,CX.class); tabHost.addTab(tabHost.newTabSpec("name") .setIndicator("name") .setContent(intent));
Activity without UI in AndroidManifest.xml, add android:theme="@android:style/Theme.NoDisplay" to the acvitity
Start new Activity When the system starts a component of other application, it starts the process for that application (if it's not
already running) and instantiates the classes needed for the component.
Start new Activity, and don't switch app to foreground if it is running on background Intent intent = new Intent(this, TergatActivity.class) intent.setFlags(Intnet.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
Start new Activity, switch app to foreground if it is running on background
Intent intent = new Intent(this, TergatActivity.class) intent.setFlags(Intnet.FLAG_ACTIVITY_NEW_TASK); getApplicationContext().startActivity(intent); //Must set flags Intnet.FLAG_ACTIVITY_NEW_TASK to intent;
Another way: you can create a service, and start Activity from service. Intent intent = new Intent(parentIntnet, target.class); intent.setAction(xxxx); intent.addCategory(xxx); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) startActivity(intent);
xxx
When press BACK key, the applicaton is exited When BACK is clicked,the activity will be closed, and then the key event is continue to transfer to the upper activity. In order to prevent application to be closed, juse to override the methods onKeyDown & onKeyUp as following, or just override onBackPressed(): boolean onKeyDown(int keyCode, KeyEvent event)
{
if (event == KeyEvent.KEYCODE_BACK)
{
return true;
}
else
{
return super.onKeyDown(keyCode, event);
}
}
How to save data when Activity is recreated 1, In non-thread environment Data will not be alerted in async way. a) Save transient state of the activity (the state of
the UI) to Bundle in method onSaveInstanceState(), and save persistent data (such as data that should be saved
to a database) to file system in method onPause(); b) Restore data in method onCreate() or onRestoreInstanceState() for transient state of the activity, and restore persistent data in onResume(). - If argument Bundle is null, activity is ever switched to background, need not to restore data - If argument Bundle is not null, Activity is killed before, restore date from argument Bundle or file system 2, In thread environment Activity contains thread that will alert data in async way. a) Declare a class name ReservedData to contains fileds that will be changed in thread and will be accessed in Activity; and then declare a static filed of type ReservedData in Activity. b) If thread depend on some Context related variables, declared these variables to be WeakReference, and after Activity is recreated, recreated those variables and reset them in method onCreate() or onRestoreInstanceState(). c) Release resources refered in the statid field declared in step a if the activity is destroyed explictly.
public class MyActivity extends Activity { private static ReservedData mReservedData = null; //Must be static
private class ReservedData //All fileds that will be accessed in both main thread and addition thread need to be synchronized. { Thread mThread = null; int num = 0; }
private class MyThread extends Thread { private boolean mExitFlag = false; private WeakReference mUiHandlerRef = null; //Context related variable, must be type of WeakReferenct;
public MyThread(Handler uiHandler) { reset(uiHandler); }
public synchronized void reset(Handler uiHandler) //Must synchronize to access mUiHandlerRef; { mUiHandlerRef = new WeakReference(uiHandler); }
public void exit() { mExitFlag = true; }
public void run() { while (!mExitFlag) { ...... synchronized (mReservedData) { mReservedData.mNum++; } notifyUi(); ...... } }
public void onCreate(Bundle savedInstanceState) { ...... if (mReservedData == null) { mReservedData = new ReservedData(); }
MyUiHandler uiHandler = new MyUiHandler(); if (mReservedData.mThread == null) { mReservedData.mThread = new MyThread(uiHandler); mReservedData.mThread.start(); } else { mReservedData.mThread.reset(uiHandler); }
if (savedInstanceState != null) //Activity is ever killed { ...... } ...... }
public void onBackPressed() //Release all data refered by static field mReservedData if user close the Activity explicitly { mReservedData.mThread.exit(); mReservedData = null; } } 3, Interact with service All data must be saved in service as static fields
Activity Animation Start target activity in an activity subclass as following:
startActivity(intent);
overridePendingTransition(R.anim.xxx, R.anim.xxx);
Dialog Activity in onCreate() function, create you own view (or load from resrouce file) and then set it as content view. a) View v = xxx; setContentView(v);
b) //customize_view.xml android:layout_width=xxx android:layout_height=xxx android:gravity=xxx android:text=xxx />
public void onCreate(xxx) { ... setContentView(R.layout.customize_view); }
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.TYPE_APPLICATION,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT); windowManager.addView(dialogText, lp);
Remove: mWindowManager.removeView(dialogText);
Display Progress bar on status bar Progress Bar Display (in onCreate): requestWindowFeature(Window.FEATURE_PROGRESS); setProgressBarVisibility(true);
Set Value: setProgress(xxx); setSecondaryProgress(xxx);
Indeterminate Progress Bar Display (in onCreate): requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setProgressBarIndeterminateVisibility(true);
Set Value: setProgress(xxx); setSecondaryProgress(xxx);
Empty Activity in Manifest file element: android:theme="@android:style/Theme.NoDisplay" /> and don't call setContentView in onCreate of the activity subclass.
Full screen @Override public void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); }
Customize Title Bar in onCreate() method: requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.xxx); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.yyy); //Here R.layout.yyy is layout of title bar
Dialog Activity add "android:theme="@android:style/Theme.Dialog" in the corresponding element in Manifest.
Query all activity with the specified intent Intent intent = new Intent(xxxx); PackageManager pm = (PackageManager)getPackageManager(); List list = pm.queryIntentActivities(intent, 0);
Another: to query all service with the specified intent: Intent intent = new Intent(xxxx);
PackageManager pm = (PackageManager)getPackageManager();
List list = pm.queryIntentServices(intent, 0);