Android 之 Activity

  1. Activity
extends ContextThemeWrapper  
implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback,View.OnCreateContextMenuListener, ComponentCallbacks2  

图1-继承关系

图2-activity生命周期 使用activity需要在AndroidManifest.xml中注册

<application  
android:name=".application.FunnyApplication"//注册项目的Application类  
      android:allowBackup="true"//可通过adb backup和adb restore来备份和恢复应用程序数据,默认为true;
      android:icon="@mipmap/ic_launcher"//app图标
      android:label="@string/app_name"//app名
      android:supportsRtl="true"//是否支持从右到左布局api 17(4.2时出现)
      android:theme="@style/app_theme">//设置主题
<activity  
      android:name=".activity.MainActivity"
      android:configChanges="orientation" />//设置方向
</application>  

启动模式

standard:标准模式;这也是系统默认的模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。
singleTop:栈顶复用模式;在这种模式下,如果Activity已经位于任务栈的栈顶,那么此Activity不会被创建,同时他的onNewIntent方法会被调用。如果Activity的实例已经存在但不是位于栈顶,那么新的Activity依然会被重新创建。
singleTask:栈内复用模式,在这种模式下,如果activty在一个栈中存在,那么多次启动此Activity都不会被重新创建,系统也会回调onNewIntent
singleInstace:单实例模式,这是一种加强的singleTask模式,他除了具有singleTask模式的特性外,还加强了一点,那就是具有此模式的Activity只能单独的位于一个任务栈中。

问答

1.如何给Activity指定启动模式?
在AndroidMenifest.xml中指定

android:name="com.ryg.chapter_1.SecondActivity"  
android:configChanges="screenLayout"  
android:label="@string/app_name"  
android:launchMode="standard"  
android:taskAffinity="com.ryg.task1" />  

通过在Intent中设置标志位来指定启动模式

Intent intent = new Intent();  
intent.setClass(A_Activity.this,B_Activity.class);  
intent.addFlags(Intenet.FLAGS_ACTIVITY_NEW_TASK);  
startIntent(intent);  

俩种指定启动模式的区别:
第二种方式的优先级高于第一种;
俩种方式在限定范围上有所不同:比如, 第一种方式无法为Activity设定FLAGACTIVITYCLEAR_TOP标识, 第二种方式无法为Activity指定sing leInstace模式。

2.横竖屏切换时候activity的生命周期?

不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次 设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法 如何将一个 Activity 设置成窗口的样式?

只需要给我们的 Activity 配置如下属性即可 android:theme="@android:style/Theme.Dialog"

如何获取当前屏幕Activity的对象? 使用ActivityLifecycleCallbacks 如何判断一个Activity是否在运行?

if (activity == null || activity.isDestroyed() || activity.isFinishing()) {  
    YES
}

同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?

可以放在不同的Task中。需要为不同的activity设置不同的affinity属性,启动activity的Intent需要包含FLAGACTIVITYNEW_TASK标记。

Application(或者Service)和Activity都可以调用Context的startActivity方法,那么在这两个地方调用startActivity有区别吗?

在Application(或者Service)需要给Intent设置Intent.FLAGACTIVITYNEW_TASK才能正常启动Activity

Fragment 的好处:

Fragment 可以使你能够将 activity 分离成多个可重用的组件,每个都有它自己的生命周期和UI。
Fragment 可以轻松得创建动态灵活的 UI 设计,可以适应于不同的屏幕尺寸。从手机到平板电脑。
Fragment 是一个独立的模块,紧紧地与 activity 绑定在一起。可以运行中动态地移除、加入、交换等。
Fragment 提供一个新的方式让你在不同的安卓设备上统一你的 UI。
Fragment 解决 Activity 间的切换不流畅,轻量切换。
Fragment 替代 TabActivity 做导航,性能更好。
Fragment 在 4.2.版本中新增嵌套 fragment 使用方法,能够生成更好的界面效果

Fragment 在你们项目中的使用

Fragment 是 android3.0 以后引入的的概念,做局部内容更新更方便,原来为了到达这一点要把多个布局放到一个 activity 里面,现在可以用多 Fragment 来代替,只有在需要的时候才加载Fragment,提高性能。

Fragment 跟 Activity 之间是如何传值的

当 Fragment 跟 Activity 绑定之后,在 Fragment 中可以直接通过 getActivity()方法获取到其绑定的 Activity 对象,这样就可以调用 Activity 的方法了。 在 Activity 中可以通过如下方法获取到Fragment 实例 FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
Fragment fragment = fragmentManager.findFragmentById(id);
获取到 Fragment 之后就可以调用 Fragment 的方法。也就实现了通信功能

Intent的原理,作用,可以传递哪些类型的参数?

intent是连接Activity, Service, BroadcastReceiver, ContentProvider四大组件的信使,,可以传递八种基本数据类型以及string, Bundle类型,以及实现了Serializable或者Parcelable的类型。
Intent可以划分成显式意图和隐式意图。
显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。 隐式意图:没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

进程的优先级

前台进程 可视进程 服务进程 后台进程 空进程

*Android Service与Activity之间的通信方式? *

通过Binder对象
当Activity通过调用bindService(Intent service, ServiceConnection conn,int flags),得到一个Service的一个对象,通过这个对象我们可以直接访问Service中的方法。 添加一个继承Binder的内部类,并添加相应的逻辑方法 重写Service的onBind方法,返回我们刚刚定义的那个内部类实 Activity中创建一个ServiceConnection的匿名内部类,并且重写里面的onServiceConnected方法和onServiceDisconnected方法,这两个方法分别会在活动与服务成功绑定以及解除绑定的时候调用,在onServiceConnected方法中,我们可以得到一个刚才那个service的binder对象,通过对这个binder对象进行向下转型,得到我们那个自定义的Binder实例,有了这个实例,做可以调用这个实例里面的具体方法进行需要的操作了
通过Broadcast Receiver
当我们的进度发生变化的时候我们发送一条广播,然后在Activity的注册广播接收器,接收到广播之后更新视图
EventBus
判断主线程

public boolean isMainThread() {  
    return Looper.getMainLooper() == Looper.myLooper();
}

张鹏宇

继续阅读此作者的更多文章