Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run(){
Resources res = Resources.getSystem();
Toast.makeText(getContext(), res.getText(com.android.internal.R.string.input_again), Toast.LENGTH_SHORT).show();
}
});
然后查看了RecentApplicationsDialog中获取字符的部分:
getContext ().getResources ().getString (com.android.internal.R.string.tipinfo);
/**
* We create the recent applications dialog just once, and it stays around
* (hidden) until activated by the user.
* 从这里其实就可以看出来端倪了
* @see PhoneWindowManager#showRecentAppsDialog
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("zmq","RecentApplicationDialog onCreate");
Context context = getContext();
if (sStatusBar == null) {
sStatusBar = (StatusBarManager) context
.getSystemService(Context.STATUS_BAR_SERVICE);
}
Window window = getWindow();
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setType(WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY);
window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
window.setTitle("Recents");
setContentView(com.android.internal.R.layout.recent_apps_dialog); //设置布局
mpPackageManager = getContext().getPackageManager();
maActivityManager = (ActivityManager) getContext().getSystemService(
Context.ACTIVITY_SERVICE);
mActivityInfo = new Intent(Intent.ACTION_MAIN).addCategory(
Intent.CATEGORY_HOME).resolveActivityInfo(mpPackageManager, 0);
mIconUtilities = new IconUtilities(getContext());
final WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(params);
window.setFlags(0, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
mIcons[0] = (TextView)findViewById(com.android.internal.R.id.button0);
mIcons[1] = (TextView)findViewById(com.android.internal.R.id.button1);
mIcons[2] = (TextView)findViewById(com.android.internal.R.id.button2);
mIcons[3] = (TextView)findViewById(com.android.internal.R.id.button3);
mIcons[4] = (TextView)findViewById(com.android.internal.R.id.button4);
mIcons[5] = (TextView)findViewById(com.android.internal.R.id.button5);
mIcons[6] = (TextView)findViewById(com.android.internal.R.id.button6);
mIcons[7] = (TextView)findViewById(com.android.internal.R.id.button7);
mNoAppsText = findViewById(com.android.internal.R.id.no_applications_message);
tipinfo = (TextView)findViewById(com.android.internal.R.id.tipinfo); //要显示提示的控件TextView
ActivityManager activityManager = (ActivityManager) getContext()
.getSystemService(Context.ACTIVITY_SERVICE);
final List list = activityManager
.getRunningTasks(1);
mGridView = (GridView) findViewById(com.android.internal.R.id.recent_gridview);
mResolveInfos = getResolveInfo();
mRecentAdapter = new RecentAdapter(mResolveInfos, context);
mGridView.setAdapter(mRecentAdapter);
if(list.get(0).topActivity.getPackageName().equals(
"com.android.zmq")){
tipinfo.setText (Resources.getSystem().getText(com.android.internal.R.string.tipsinfo));
}
mGridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
try {
if (mRecentAdapter.getmResolveInfos() != null) {
RecentTag recentTag = getTag(mRecentAdapter
.getmResolveInfos().get(arg2));
if (recentTag != null)
{
if(list.get(0).topActivity.getPackageName().equals(
"com.android.zmq"))
{
isForceStopOne = true;
forceStopPackage(recentTag);
mRecentAdapter.setmResolveInfos(getResolveInfo());
mRecentAdapter.notifyDataSetChanged();
isForceStopOne = false;
}else{
switchTo(recentTag);
dismiss();
}
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
});
}
知道了原因,问题就比较好解决了。既然每次都会跑onStart,那么我们就把字符的显示放在onStart中。
/**
* Set up and show the recent activities dialog.
*/
@Override
public void onStart() {
super.onStart();
Log.d("zmq","RecentApplicationDialog onStart");
mRecentAdapter.setmResolveInfos(getResolveInfo());
mRecentAdapter.notifyDataSetChanged();
if (sStatusBar != null) {
sStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
}
ActivityManager am = (ActivityManager) getContext()
.getSystemService(Context.ACTIVITY_SERVICE);
final List runList = am.getRunningTasks(1);
//显示字符,这样就可以每次都切换到啦。
if(runList.get(0).topActivity.getPackageName().equals(
"com.android.zmq")){
tipinfo.setText (Resources.getSystem().getText(com.android.internal.R.string.tipsinfo));
}
else{
tipinfo.setText(Resources.getSystem().getText(com.android.internal.R.string.recent_remove_message_pb));
}
// receive broadcasts
getContext().registerReceiver(mBroadcastReceiver, mBroadcastIntentFilter);
mHandler.removeCallbacks(mCleanup);
mGridView.setFocusable(true);
mGridView.setFocusableInTouchMode(true);
mGridView.requestFocus();
}
Protected Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
void | onCreate( Bundle savedInstanceState)
Similar to onCreate(Bundle) , you should initialize your dialog in this method, including calling setContentView(View) .
|
||||||||||
void | onStart()
Called when the dialog is starting.
|
||||||||||
void | onStop()
Called to tell you that you're stopping.
|
void showOrHideRecentAppsDialog(final int behavior) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (mRecentAppsDialog == null) {
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
}
if (mRecentAppsDialog.isShowing()) {
switch (behavior) {
case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
case RECENT_APPS_BEHAVIOR_DISMISS:
mRecentAppsDialog.dismiss();
break;
case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
mRecentAppsDialog.dismissAndSwitch();
break;
case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
default:
break;
}
} else {
switch (behavior) {
case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
mRecentAppsDialog.show();
break;
case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
try {
mWindowManager.setInTouchMode(false);
} catch (RemoteException e) {
}
mRecentAppsDialog.show();
break;
case RECENT_APPS_BEHAVIOR_DISMISS:
case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
default:
break;
}
}
}
});
}
在Dialog中,show方法:
/**
* Start the dialog and display it on screen. The window is placed in the
* application layer and opaque. Note that you should not override this
* method to do initialization when the dialog is shown, instead implement
* that in {@link #onStart}.
*/
public void show() {
Log.d("zmq","Dialog show");
if (mShowing) {
if (mDecor != null) {
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
//mCreated初始值为false,即第一次是会执行的
if (!mCreated) {
dispatchOnCreate(null);
}
onStart();
mDecor = mWindow.getDecorView();
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
final ApplicationInfo info = mContext.getApplicationInfo();
mWindow.setDefaultIcon(info.icon);
mWindow.setDefaultLogo(info.logo);
mActionBar = new ActionBarImpl(this);
}
WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
l = nl;
}
try {
mWindowManager.addView(mDecor, l);
mShowing = true;
sendShowMessage();
} finally {
}
}
可以看到,只有第一次的时候,mCreated为false,才会运行dispatchOnCreate,在 dispatchOnCreate中:
// internal method to make sure mcreated is set properly without requiring
// users to call through to super in onCreate
void dispatchOnCreate(Bundle savedInstanceState) {
Log.d("zmq","Dialog dispatchOnCreate");
Log.d("zmq","Dialog dispatchOnCreate mCreated = "+mCreated);
if(savedInstanceState!=null){
Log.d("zmq","Dialog dispatchOnCreate savedInstanceState != null");
}
else{
Log.d("zmq","Dialog dispatchOnCreate savedInstanceState == null");
}
//mCreated第一次是false
if (!mCreated) {
//执行RecentApplicationsDialog中的onCreate
onCreate(savedInstanceState);
mCreated = true; //设置为true,以后就不再执行。这里就是根源啦
}
}
/**
* Dismiss this dialog, removing it from the screen. This method can be
* invoked safely from any thread. Note that you should not override this
* method to do cleanup when the dialog is dismissed, instead implement
* that in {@link #onStop}.
*/
@Override
public void dismiss() {
Log.d("zmq","Dialog dismiss");
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
void dismissDialog() {
Log.d("zmq","Dialog dismissDialog");
if (mDecor == null || !mShowing) {
return;
}
if (mWindow.isDestroyed()) {
Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
return;
}
try {
mWindowManager.removeViewImmediate(mDecor);
} finally {
if (mActionMode != null) {
mActionMode.finish();
}
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
sendDismissMessage();
}
}