您的位置:首页 > 移动开发 > Android开发

android activity相关杂谈

2020-04-01 18:51 1966 查看

看Activity启动流程中,记一下关于Launcher、SystemServer、Application的一些笔记。

Launcher

Launcher在onCreate时会创建LauncherModel并调用startLoader,创建LoaderTask。调用 loadWorkspace、bindWorkspace等。loadWorkspace会查询获取widget、shortcut、folder等一系列ItemInfo。对于ShortcutInfo,解析出包含intent,user等信息。这些ItemInfo将通过bindWorkspace传递给Launcher.bindItems,对于ShortcutInfo将创建BubbleTextView,并setTag将ShortcutInfo注入。于是乎,Launcher的onclick可以将view中的tag取出,若tag是ShortcutInfo类型,自然而然可以拿到用于启动activity的intent,和相关的user信息。

SystemServer

Activity启动流程中,LauncherAppsService.startActivityAsUser()使用了自己的Context:

public void startActivityAsUser(String callingPackage,
ComponentName component, Rect sourceBounds,
Bundle opts, UserHandle user) throws RemoteException {
...
for (int i = 0; i < size; ++i) {
ActivityInfo activityInfo = apps.get(i).activityInfo;
if (activityInfo.packageName.equals(component.getPackageName()) &&
activityInfo.name.equals(component.getClassName())) {
// Found an activity with category launcher that matches
// this component so ok to launch.
launchIntent.setComponent(component);
// 这里的context是SystemServer创建ContextImpl
mContext.startActivityAsUser(launchIntent, opts, user);
return;
}
}
...
}

那么context是从哪来的呢?我们知道LauncherAppsService是由SystemServer启动的:

// SystemServer
private void startOtherServices() {
...
mSystemServiceManager.startService(LauncherAppsService.class);
...
}

// SystemManagerService
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
...
}
return startService(serviceClass);
}
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
// log以及检查是否是SystemService的子类
...
final T service;
try {
// 利用反射并且把mContext注入。
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
// 一系列exception的检查
...
}
// 注册对应的服务。
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}

可以看到LauncherAppsService的context由SystemMangerService传入,再回溯回去,System初始化的时候,创建了自己的context,并且传给了SystemMangerService。

// SystemServer
private void run() {
try {
...
// Initialize the system context.
createSystemContext();

// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
}
}
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

// ActvivtyThread
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
// 注意这里还会创建ApplicationThread.
// ApplicationThread 继承了 IApplicationThread.stub
// 在创建Activity的时候使用了该Binder
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
// 这里创建的是系统的ActivityThread
if (!system) {
...
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
/* 1. 这里创建的context,个人没看出有什么用,这个引用没有用过
* 并且下面makeApplication中使用相同的参数也创建了一个context作为内部成员,还望高手指点
* 2.getSystemContext会创建对应的LoLoadedAPK,加载系统资源等。
*/
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
// mPackageInfo是LoadedAPK的实例,创建对应的application
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}

// LoadedAPK
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
...
Application app = null;

String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}

try {
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 这里newApplication通过反射创建appClass的实例,并将appContext付给app的baseContext.
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
...
return app;
}

Application

看官方注释说,Application维持着全局的应用状态,在应用的进程被创建时,是第一个被实例化的类,自然包括了Activity等组件了,应用可以继承该类,通过设置manifest中application的"android:name"标签。

public class Application extends ContextWrapper implements ComponentCallbacks2 {
private ArrayList<ComponentCallbacks> mComponentCallbacks =
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;

/** @hide */
public LoadedApk mLoadedApk;

public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}

/**
* Callback interface for use with {@link Application#registerOnProvideAssistDataListener}
* and {@link Application#unregisterOnProvideAssistDataListener}.
*/
public interface OnProvideAssistDataListener {
/**
* This is called when the user is requesting an assist, to build a full
* {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
* application.  You can override this method to place into the bundle anything
* you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
* of the assist Intent.
*/
public void onProvideAssistData(Activity activity, Bundle data);
}

public Application() {
super(null);
}

/**
* Called when the application is starting, before any activity, service,
* or receiver objects (excluding content providers) have been created.
* Implementations should be as quick as possible (for example using
* lazy initialization of state) since the time spent in this function
* directly impacts the performance of starting the first activity,
* service, or receiver in a process.
* If you override this method, be sure to call super.onCreate().
*/
@CallSuper
public void onCreate() {
}

/**
* This method is for use in emulated process environments.  It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/
@CallSuper
public void onTerminate() {
}

@CallSuper
public void onConfigurationChanged(Configuration newConfig) {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
}
}
}

@CallSuper
public void onLowMemory() {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onLowMemory();
}
}
}
...

看成员变量和接口可以发现,Activity的七个回调,低内存等事件,Application是可以监听到的。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
ljt326053002 发布了6 篇原创文章 · 获赞 0 · 访问量 109 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: