现在做一个功能,屏蔽原生andorid 系统的清除历史栈
1. 首先查到,back 按键,home 按键,清除历史栈按键的加载,在systemUI中PhoneStatusBar。
public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
super.start(); // calls createAndAddWindows()
addNavigationBar();
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext);
mHeadsUpObserver.onChange(true); // set up
if (ENABLE_HEADS_UP) {
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SETTING_HEADS_UP), true,
mHeadsUpObserver);
}
}
2.加载3个按键的图标
// For small-screen devices (read: phones) that lack hardware navigation buttons
private void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
updateSearchPanel();
}
3, 找到了系统的清除历史栈的按键处理事件
private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
public void onClick(View v) {
awakenDreams();
toggleRecentApps();
}
};
4, 如果可以,目前可以直接先屏蔽掉onClick 事件,接着分析,发送一条信息去handler 处理
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks {
@Override
public void toggleRecentApps() {
int msg = MSG_TOGGLE_RECENTS_PANEL;
mHandler.removeMessages(msg);
mHandler.sendEmptyMessage(msg);
}
5.找到了handler 的处理流程, toggleRecentsActivity();,包含打开历史栈,关闭历史栈,等等的操作
protected class H extends Handler {
public void handleMessage(Message m) {
Intent intent;
switch (m.what) {
case MSG_TOGGLE_RECENTS_PANEL:
toggleRecentsActivity();
break;
case MSG_CLOSE_RECENTS_PANEL:
closeRecents();
break;
case MSG_PRELOAD_RECENT_APPS:
preloadRecentTasksList();
break;
case MSG_CANCEL_PRELOAD_RECENT_APPS:
cancelPreloadingRecentTasksList();
break;
case MSG_OPEN_SEARCH_PANEL:
if (DEBUG) Log.d(TAG, "opening search panel");
if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) {
mSearchPanelView.show(true, true);
onShowSearchPanel();
}
break;
case MSG_CLOSE_SEARCH_PANEL:
if (DEBUG) Log.d(TAG, "closing search panel");
if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
mSearchPanelView.show(false, true);
onHideSearchPanel();
}
break;
}
}
}
6, 首先看看打开应用的历史栈
protected void toggleRecentsActivity() {
if (mRecents != null) {
mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView());
}
}
public class Recents extends SystemUI implements RecentsComponent {
@Override
public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
if (DEBUG) Log.d(TAG, "toggle recents panel");
try {
TaskDescription firstTask = RecentTasksLoader.getInstance(mContext).getFirstTask();
Intent intent = new Intent(RecentsActivity.TOGGLE_RECENTS_INTENT);
intent.setClassName("com.android.systemui",
"com.android.systemui.recent.RecentsActivity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
if (firstTask == null) {
if (RecentsActivity.forceOpaqueBackground(mContext)) {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.recents_launch_from_launcher_enter,
R.anim.recents_launch_from_launcher_exit);
mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
UserHandle.USER_CURRENT));
} else {
// The correct window animation will be applied via the activity's style
mContext.startActivityAsUser(intent, new UserHandle(
UserHandle.USER_CURRENT));
}
} else {
Bitmap first = null;
if (firstTask.getThumbnail() instanceof BitmapDrawable) {
first = ((BitmapDrawable) firstTask.getThumbnail()).getBitmap();
} else {
first = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
Drawable d = RecentTasksLoader.getInstance(mContext).getDefaultThumbnail();
d.draw(new Canvas(first));
}
final Resources res = mContext.getResources();
float thumbWidth = res
.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width);
float thumbHeight = res
.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height);
if (first == null) {
throw new RuntimeException("Recents thumbnail is null");
}
if (first.getWidth() != thumbWidth || first.getHeight() != thumbHeight) {
first = Bitmap.createScaledBitmap(first, (int) thumbWidth, (int) thumbHeight,
true);
if (first == null) {
throw new RuntimeException("Recents thumbnail is null");
}
}
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
// calculate it here, but consider moving it elsewhere
// first, determine which orientation you're in.
final Configuration config = res.getConfiguration();
int x, y;
if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
float appLabelLeftMargin = res.getDimensionPixelSize(
R.dimen.status_bar_recents_app_label_left_margin);
float appLabelWidth = res.getDimensionPixelSize(
R.dimen.status_bar_recents_app_label_width);
float thumbLeftMargin = res.getDimensionPixelSize(
R.dimen.status_bar_recents_thumbnail_left_margin);
float thumbBgPadding = res.getDimensionPixelSize(
R.dimen.status_bar_recents_thumbnail_bg_padding);
float width = appLabelLeftMargin +
+appLabelWidth
+ thumbLeftMargin
+ thumbWidth
+ 2 * thumbBgPadding;
x = (int) ((dm.widthPixels - width) / 2f + appLabelLeftMargin + appLabelWidth
+ thumbBgPadding + thumbLeftMargin);
y = (int) (dm.heightPixels
- res.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height)
- thumbBgPadding);
if (layoutDirection == View.LAYOUT_DIRECTION_RTL) {
x = dm.widthPixels - x - res.getDimensionPixelSize(
R.dimen.status_bar_recents_thumbnail_width);
}
} else { // if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
float thumbTopMargin = res.getDimensionPixelSize(
R.dimen.status_bar_recents_thumbnail_top_margin);
float thumbBgPadding = res.getDimensionPixelSize(
R.dimen.status_bar_recents_thumbnail_bg_padding);
float textPadding = res.getDimensionPixelSize(
R.dimen.status_bar_recents_text_description_padding);
float labelTextSize = res.getDimensionPixelSize(
R.dimen.status_bar_recents_app_label_text_size);
Paint p = new Paint();
p.setTextSize(labelTextSize);
float labelTextHeight = p.getFontMetricsInt().bottom
- p.getFontMetricsInt().top;
float descriptionTextSize = res.getDimensionPixelSize(
R.dimen.status_bar_recents_app_description_text_size);
p.setTextSize(descriptionTextSize);
float descriptionTextHeight = p.getFontMetricsInt().bottom
- p.getFontMetricsInt().top;
float statusBarHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
float recentsItemTopPadding = statusBarHeight;
float height = thumbTopMargin
+ thumbHeight
+ 2 * thumbBgPadding + textPadding + labelTextHeight
+ recentsItemTopPadding + textPadding + descriptionTextHeight;
float recentsItemRightPadding = res
.getDimensionPixelSize(R.dimen.status_bar_recents_item_padding);
float recentsScrollViewRightPadding = res
.getDimensionPixelSize(R.dimen.status_bar_recents_right_glow_margin);
x = (int) (dm.widthPixels - res
.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width)
- thumbBgPadding - recentsItemRightPadding
- recentsScrollViewRightPadding);
y = (int) ((dm.heightPixels - statusBarHeight - height) / 2f + thumbTopMargin
+ recentsItemTopPadding + thumbBgPadding + statusBarHeight);
}
ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(
statusBarView,
first, x, y,
new ActivityOptions.OnAnimationStartedListener() {
public void onAnimationStarted() {
Intent intent =
new Intent(RecentsActivity.WINDOW_ANIMATION_START_INTENT);
intent.setPackage("com.android.systemui");
mContext.sendBroadcastAsUser(intent,
new UserHandle(UserHandle.USER_CURRENT));
}
});
intent.putExtra(RecentsActivity.WAITING_FOR_WINDOW_ANIMATION_PARAM, true);
mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
UserHandle.USER_CURRENT));
}
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Failed to launch RecentAppsIntent", e);
}
}
7. 找到 recentActivity 的实现,其实每一个滑动事件都在
systemui/recent/RecentsHorizontalScrollView.java
systemui/recent/RecentsVerticalScrollView.java
中做了处理因为android 支持横竖屏操作,所有在两个类中不中做了处理
public class RecentsActivity extends Activity {
private static final String TAG = "RecentsActivity";
public static final String TOGGLE_RECENTS_INTENT = "com.android.systemui.recent.action.TOGGLE_RECENTS";
public static final String PRELOAD_INTENT = "com.android.systemui.recent.action.PRELOAD";
public static final String CANCEL_PRELOAD_INTENT = "com.android.systemui.recent.CANCEL_PRELOAD";
public static final String CLOSE_RECENTS_INTENT = "com.android.systemui.recent.action.CLOSE";
public static final String WINDOW_ANIMATION_START_INTENT = "com.android.systemui.recent.action.WINDOW_ANIMATION_START";
public static final String PRELOAD_PERMISSION = "com.android.systemui.recent.permission.PRELOAD";
public static final String WAITING_FOR_WINDOW_ANIMATION_PARAM = "com.android.systemui.recent.WAITING_FOR_WINDOW_ANIMATION";
private static final String WAS_SHOWING = "was_showing";
private RecentsPanelView mRecentsPanel;
8.在RecentsVerticalScrollView中的onTouchEvent 中做了处理。
@Override
public boolean onTouchEvent(MotionEvent ev) {
9. 后续做一些杀掉应用的操作。
public void handleSwipe(View view) {
TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription;
if (ad == null) {
Log.v(TAG, "Not able to find activity description for swiped task; view=" + view +
" tag=" + view.getTag());
return;
}
if (DEBUG) Log.v(TAG, "Jettison " + ad.getLabel());
mRecentTaskDescriptions.remove(ad);
mRecentTasksLoader.remove(ad);
/*
* SPRD: add for ramoptimizer
* @{
*/
//RecentsScrollView scrollView = (RecentsScrollView) mRecentsContainer;
if(mRecentsContainer.ifDeletePackage(ad.packageName)) {
mSprdLockListEditor.remove(ad.packageName);
mSprdLockListEditor.apply();
}
/*
* @}
*/
// Handled by widget containers to enable LayoutTransitions properly
// mListAdapter.notifyDataSetChanged();
if (mRecentTaskDescriptions.size() == 0) {
/* SPRD: modify for bug 259124
* @orig dismissAndGoBack();
* @{
*/
mRecentsNoApps.setAlpha(1f);
mRecentsNoApps.setVisibility(View.VISIBLE);
/*
* @}
*/
}
// Currently, either direction means the same thing, so ignore direction and remove
// the task.
final ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
// Accessibility feedback
setContentDescription(
mContext.getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
setContentDescription(null);
}
}