- Docs
- Activitys Fundamentals
http://developer.android.com/guide/topics/fundamentals/activities.html - 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. - xxx
- Types
- Activity
- Configuraton
(Refer:
http://developer.android.com/guide/topics/resources/runtime-changes.html
http://developer.android.com/resources/articles/faster-screen-orientation-change.html
)
- 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.
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
} - Handle Configuration Change Event Yourself
public class MyActivity extends Activity
{
private Configuration m_curConfig = null;
private ImageView m_imgView = null;
private TextView m_txtView = null;
public void onCreate(Bundle savedInstanceState)
{
....
m_curConfig = new Configuration();
m_curConfig.setToDefaults();
m_imgView = (ImageView)findViewById(xxx);
m_txtView = (TextView)findViewById(xxx);
}
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
}
if(m_curConfig.orientation != newConfig.orientation) //orientation changed
{
Drawable d = getResources().getDrawable(R.drawable.xxx);
m_imgView.setImageDrawable(d);
}
super.onConfigurationChanged(newConfig);
}
}
- 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 onRestoreInstanceState() (or onCreate()), as discussed in the previous section.
(Refer to: http://developer.android.com/guide/topics/fundamentals/activities.html)
- 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
- 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
- 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);
}
}
boolean onKeyUp(int keyCode, KeyEvent event)
{
if (event == KeyEvent.KEYCODE_BACK)
{
finish();
return true;
}
else
{
return super.onKeyUp(keyCode, event);
}
}
- Hide and show activity
Hide: Activity.moveTaskToBack
Show: ActivityManager.moveTaskToFront
- Launch activity
- Launch activity of current application
Intent intent = new Intent(context, MyActivity.class)
context.startActivity(intent);
- Launch activity of other applications
1st way:
Intent intent = new Intent();
intent.setAction(xxx):
intent.setCategory(xxx); intent.setCategory(Intent.CATEGORY_DEFAULT); //Necessary
startActivity(intent);
2nd way:
Intent intent = new Intent();
intent.setClassName("com.test.package", "com.test.package.MyActivity"); //or intent.setComponentName(new ComponentName("com.test.package", "com.test.package.MyActivity"));
context.startActivity(intent);
- xxx
- xxx
- 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();
......
}
}
private synchronized void notifyUi() //Must synchronize to access mUiHandlerRef;
{
if (mUiHandlerRef != null)
{
Handler handler = mUiHandlerRef.get();
if (handler != null)
{
Message msg = handler.obtain(xxx);
msg.sendToTarget();
}
}
}
}
private MyUiHandler extends Handler
{
public void handleMessage(Message msg)
{
......
synchronized (mReservedData)
{
System.out.println("Num = " mReservedData.mNum);
}
}
}
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);
}
- Tips
- 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.
- xxx
- xxx
阅读(1609) | 评论(0) | 转发(0) |