Work on settings launch speed

Move some stuff to the background, avoid doing other things.

Change-Id: I145172efa16f81c2f377f07744c8f88145e2ed1d
This commit is contained in:
Jason Monk
2015-12-02 15:38:38 -05:00
parent a405e7b79b
commit fd2c722418
3 changed files with 109 additions and 77 deletions

View File

@@ -32,6 +32,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.nfc.NfcAdapter; import android.nfc.NfcAdapter;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
@@ -453,6 +454,7 @@ public class SettingsActivity extends SettingsDrawerActivity
@Override @Override
protected void onCreate(Bundle savedState) { protected void onCreate(Bundle savedState) {
super.onCreate(savedState); super.onCreate(savedState);
long startTime = System.currentTimeMillis();
// Should happen before any call to getIntent() // Should happen before any call to getIntent()
getMetaData(); getMetaData();
@@ -506,7 +508,15 @@ public class SettingsActivity extends SettingsDrawerActivity
if (mIsShowingDashboard) { if (mIsShowingDashboard) {
// Run the Index update only if we have some space // Run the Index update only if we have some space
if (!Utils.isLowStorage(this)) { if (!Utils.isLowStorage(this)) {
long indexStartTime = System.currentTimeMillis();
AsyncTask.execute(new Runnable() {
@Override
public void run() {
Index.getInstance(getApplicationContext()).update(); Index.getInstance(getApplicationContext()).update();
}
});
if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
+ (System.currentTimeMillis() - indexStartTime) + " ms");
} else { } else {
Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!"); Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
} }
@@ -621,6 +631,8 @@ public class SettingsActivity extends SettingsDrawerActivity
} }
mHomeActivitiesCount = getHomeActivitiesCount(); mHomeActivitiesCount = getHomeActivitiesCount();
if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
+ " ms");
} }
private int getHomeActivitiesCount() { private int getHomeActivitiesCount() {
@@ -955,6 +967,18 @@ public class SettingsActivity extends SettingsDrawerActivity
} }
private void updateTilesList() { private void updateTilesList() {
// Generally the items that are will be changing from these updates will
// not be in the top list of tiles, so run it in the background and the
// SettingsDrawerActivity will pick up on the updates automatically.
AsyncTask.execute(new Runnable() {
@Override
public void run() {
doUpdateTilesList();
}
});
}
private void doUpdateTilesList() {
PackageManager pm = getPackageManager(); PackageManager pm = getPackageManager();
final UserManager um = UserManager.get(this); final UserManager um = UserManager.get(this);
final boolean isAdmin = um.isAdminUser(); final boolean isAdmin = um.isAdminUser();
@@ -1009,7 +1033,7 @@ public class SettingsActivity extends SettingsDrawerActivity
if (UserHandle.MU_ENABLED && !isAdmin) { if (UserHandle.MU_ENABLED && !isAdmin) {
// When on restricted users, disable all extra categories (but only the settings ones). // When on restricted users, disable all extra categories (but only the settings ones).
List<DashboardCategory> categories = getDashboardCategories(true); List<DashboardCategory> categories = getDashboardCategories();
for (DashboardCategory category : categories) { for (DashboardCategory category : categories) {
for (DashboardTile tile : category.tiles) { for (DashboardTile tile : category.tiles) {
ComponentName component = tile.intent.getComponent(); ComponentName component = tile.intent.getComponent();
@@ -1020,8 +1044,6 @@ public class SettingsActivity extends SettingsDrawerActivity
} }
} }
} }
updateDrawer();
} }
private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin, private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,

View File

@@ -16,13 +16,7 @@
package com.android.settings.dashboard; package com.android.settings.dashboard;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log; import android.util.Log;
@@ -38,11 +32,14 @@ import com.android.settings.R;
import com.android.settings.Settings; import com.android.settings.Settings;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import java.util.List; import java.util.List;
public class DashboardSummary extends InstrumentedFragment { public class DashboardSummary extends InstrumentedFragment
public static final boolean DEBUG = true; implements SettingsDrawerActivity.CategoryListener {
public static final boolean DEBUG = false;
private static final boolean DEBUG_TIMING = false;
private static final String TAG = "DashboardSummary"; private static final String TAG = "DashboardSummary";
public static final String[] INITIAL_ITEMS = new String[] { public static final String[] INITIAL_ITEMS = new String[] {
@@ -56,8 +53,6 @@ public class DashboardSummary extends InstrumentedFragment {
private static final int MSG_REBUILD_UI = 1; private static final int MSG_REBUILD_UI = 1;
private final HomePackageReceiver mHomePackageReceiver = new HomePackageReceiver();
private RecyclerView mDashboard; private RecyclerView mDashboard;
private DashboardAdapter mAdapter; private DashboardAdapter mAdapter;
private SummaryLoader mSummaryLoader; private SummaryLoader mSummaryLoader;
@@ -71,11 +66,19 @@ public class DashboardSummary extends InstrumentedFragment {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
long startTime = System.currentTimeMillis();
List<DashboardCategory> categories = List<DashboardCategory> categories =
((SettingsActivity) getActivity()).getDashboardCategories(true); ((SettingsActivity) getActivity()).getDashboardCategories();
mAdapter = new DashboardAdapter(getContext(), categories); mSummaryLoader = new SummaryLoader(getActivity(), categories);
mSummaryLoader = new SummaryLoader(getActivity(), mAdapter, categories);
setHasOptionsMenu(true); setHasOptionsMenu(true);
if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
+ " ms");
}
@Override
public void onDestroy() {
mSummaryLoader.release();
super.onDestroy();
} }
@Override @Override
@@ -90,14 +93,7 @@ public class DashboardSummary extends InstrumentedFragment {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
sendRebuildUI(); ((SettingsDrawerActivity) getActivity()).addCategoryListener(this);
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addDataScheme("package");
getActivity().registerReceiver(mHomePackageReceiver, filter);
mSummaryLoader.setListening(true); mSummaryLoader.setListening(true);
} }
@@ -105,7 +101,7 @@ public class DashboardSummary extends InstrumentedFragment {
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
getActivity().unregisterReceiver(mHomePackageReceiver); ((SettingsDrawerActivity) getActivity()).remCategoryListener(this);
mSummaryLoader.setListening(false); mSummaryLoader.setListening(false);
} }
@@ -123,10 +119,10 @@ public class DashboardSummary extends InstrumentedFragment {
mDashboard.setLayoutManager(llm); mDashboard.setLayoutManager(llm);
mDashboard.setHasFixedSize(true); mDashboard.setHasFixedSize(true);
rebuildUI(getContext()); rebuildUI();
} }
private void rebuildUI(Context context) { private void rebuildUI() {
if (!isAdded()) { if (!isAdded()) {
Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added"); Log.w(TAG, "Cannot build the DashboardSummary UI yet as the Fragment is not added");
return; return;
@@ -135,7 +131,7 @@ public class DashboardSummary extends InstrumentedFragment {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
// TODO: Cache summaries from old categories somehow. // TODO: Cache summaries from old categories somehow.
List<DashboardCategory> categories = List<DashboardCategory> categories =
((SettingsActivity) getActivity()).getDashboardCategories(true); ((SettingsActivity) getActivity()).getDashboardCategories();
boolean showingAll = mAdapter != null && mAdapter.isShowingAll(); boolean showingAll = mAdapter != null && mAdapter.isShowingAll();
mAdapter = new DashboardAdapter(getContext(), categories); mAdapter = new DashboardAdapter(getContext(), categories);
mSummaryLoader.setAdapter(mAdapter); mSummaryLoader.setAdapter(mAdapter);
@@ -146,29 +142,8 @@ public class DashboardSummary extends InstrumentedFragment {
Log.d(TAG, "rebuildUI took: " + delta + " ms"); Log.d(TAG, "rebuildUI took: " + delta + " ms");
} }
private void sendRebuildUI() {
if (!mHandler.hasMessages(MSG_REBUILD_UI)) {
mHandler.sendEmptyMessage(MSG_REBUILD_UI);
}
}
private Handler mHandler = new Handler() {
@Override @Override
public void handleMessage(Message msg) { public void onCategoriesChanged() {
switch (msg.what) { rebuildUI();
case MSG_REBUILD_UI: {
final Context context = getActivity();
rebuildUI(context);
} break;
} }
}
};
private class HomePackageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
rebuildUI(context);
}
}
} }

View File

@@ -16,9 +16,11 @@
package com.android.settings.dashboard; package com.android.settings.dashboard;
import android.app.Activity; import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
@@ -39,38 +41,48 @@ public class SummaryLoader {
private final ArrayMap<SummaryProvider, DashboardTile> mSummaryMap = new ArrayMap<>(); private final ArrayMap<SummaryProvider, DashboardTile> mSummaryMap = new ArrayMap<>();
private final List<DashboardTile> mTiles = new ArrayList<>(); private final List<DashboardTile> mTiles = new ArrayList<>();
private final Worker mWorker;
private final Handler mHandler;
private final HandlerThread mWorkerThread;
private DashboardAdapter mAdapter; private DashboardAdapter mAdapter;
public SummaryLoader(Activity activity, DashboardAdapter adapter, public SummaryLoader(Activity activity, List<DashboardCategory> categories) {
List<DashboardCategory> categories) { mHandler = new Handler();
mWorkerThread = new HandlerThread("SummaryLoader");
mWorkerThread.start();
mWorker = new Worker(mWorkerThread.getLooper());
mActivity = activity; mActivity = activity;
mAdapter = adapter;
for (int i = 0; i < categories.size(); i++) { for (int i = 0; i < categories.size(); i++) {
List<DashboardTile> tiles = categories.get(i).tiles; List<DashboardTile> tiles = categories.get(i).tiles;
for (int j = 0; j < tiles.size(); j++) { for (int j = 0; j < tiles.size(); j++) {
DashboardTile tile = tiles.get(j); DashboardTile tile = tiles.get(j);
SummaryProvider provider = getSummaryProvider(tile); mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
if (provider != null) {
mSummaryMap.put(provider, tile);
} }
} }
} }
public void release() {
mWorkerThread.quit();
} }
public void setAdapter(DashboardAdapter adapter) { public void setAdapter(DashboardAdapter adapter) {
mAdapter = adapter; mAdapter = adapter;
} }
public void setSummary(SummaryProvider provider, CharSequence summary) { public void setSummary(SummaryProvider provider, final CharSequence summary) {
DashboardTile tile = mSummaryMap.get(provider); final DashboardTile tile = mSummaryMap.get(provider);
mHandler.post(new Runnable() {
@Override
public void run() {
tile.summary = summary; tile.summary = summary;
mAdapter.notifyChanged(tile); mAdapter.notifyChanged(tile);
} }
});
}
public void setListening(boolean listening) { public void setListening(boolean listening) {
for (SummaryProvider provider : mSummaryMap.keySet()) { mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget();
provider.setListening(listening);
}
} }
private SummaryProvider getSummaryProvider(DashboardTile tile) { private SummaryProvider getSummaryProvider(DashboardTile tile) {
@@ -107,14 +119,7 @@ public class SummaryLoader {
} }
private Bundle getMetaData(DashboardTile tile) { private Bundle getMetaData(DashboardTile tile) {
// TODO: Cache this in TileUtils so this doesn't need to be loaded again. return tile.metaData;
try {
ActivityInfo activityInfo = mActivity.getPackageManager().getActivityInfo(
tile.intent.getComponent(), PackageManager.GET_META_DATA);
return activityInfo.metaData;
} catch (PackageManager.NameNotFoundException e) {
return null;
}
} }
public interface SummaryProvider { public interface SummaryProvider {
@@ -124,4 +129,34 @@ public class SummaryLoader {
public interface SummaryProviderFactory { public interface SummaryProviderFactory {
SummaryProvider createSummaryProvider(Activity activity, SummaryLoader summaryLoader); SummaryProvider createSummaryProvider(Activity activity, SummaryLoader summaryLoader);
} }
private class Worker extends Handler {
private static final int MSG_GET_PROVIDER = 1;
private static final int MSG_SET_LISTENING = 2;
public Worker(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_GET_PROVIDER:
DashboardTile tile = (DashboardTile) msg.obj;
SummaryProvider provider = getSummaryProvider(tile);
if (provider != null) {
if (DEBUG) Log.d(TAG, "Creating " + tile);
mSummaryMap.put(provider, tile);
}
break;
case MSG_SET_LISTENING:
boolean listening = msg.arg1 != 0;
if (DEBUG) Log.d(TAG, "Listening " + listening);
for (SummaryProvider p : mSummaryMap.keySet()) {
p.setListening(listening);
}
break;
}
}
}
} }