Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2028456
  • 博文数量: 413
  • 博客积分: 10926
  • 博客等级: 上将
  • 技术积分: 3862
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-09 18:14
文章分类

全部博文(413)

文章存档

2015年(5)

2014年(1)

2013年(5)

2012年(6)

2011年(138)

2010年(85)

2009年(42)

2008年(46)

2007年(26)

2006年(59)

分类: 嵌入式

2010-07-30 17:53:55

  1. 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
  2. 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
  3. Types
    1. 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. 
          (
          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
          }
        • 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 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
    2. 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.
    3. TabActivity
    4. ListActivity
      An activity that displays a list of items. ListActivity hosts a ListView object.
    5. LauncherActivity
      Displays a list of all activities which can be performed for a given intent.
    6. PreferenceActivity
    7. NativeActivity
      An activity that will be implemented purely in native code. (You can find such sample native-activity under \samples\native-activity\)
    8. xxx
  4. FAQ
    1. 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.
    2. 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.
    3. 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));
    4. Activity without UI
      in AndroidManifest.xml, add android:theme="@android:style/Theme.NoDisplay" to the acvitity
    5. 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
    6. 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);
          }
      }
    7. Hide and show activity
      Hide: Activity.moveTaskToBack
      Show: ActivityManager.moveTaskToFront
    8. 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
    9. xxx
  5. 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

  6. Activity Animation
    Start target activity in an activity subclass as following:
    startActivity(intent);
    overridePendingTransition(R.anim.xxx, R.anim.xxx);
  7. 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);
    }

  8. Tips
    • Add/Remoev Widget With WindowManger

      Add:
      WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);

      TextView dialogText = (TextView) inflate.inflate(R.layout.list_position, null);

      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);
    • xxx
  9. xxx
阅读(964) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~