Intent的flag 标志:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-- Android四大启动模式:standard、singleTop、singleTask、singleInstance 及应用场景:
- Android 生命周期监听- https://github.com/LillteZheng/ZlifeCycle
Activity生命周期监听接口:ActivityLifecycleCallbacks
使用黑科技启动未注册的Activity- https://mp.weixin.qq.com/s/gzg0a_afY0459w07WvuXkQ
使用黑科技启动未注册的Activity- https://blog.csdn.net/huangliniqng/article/details/89643106
对startActivity方法进行Hook,这里采用对AMN Hook的方式
-- Activity四大启动模式与onNewIntent();
1.standard默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。应用场景:绝大多数Activity。
2.singleTop,栈顶复用模式,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法。避免栈顶的activity被重复的创建。应用场景:在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用
singleTop,否则每次点击都会新建一个Activity。
3.singleTask,栈内复用模式, activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity。
应用场景:大多数App的主页。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。
4.singleInstance,单一实例模式,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个
activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。
SingleTask全局MainActivity,SingleInstance视频播放页Activity,singleTop广告启动页Activity。
-- 关于onNewIntent的使用- https://blog.csdn.net/lihenair/article/details/28892921
当我们在activity的启动模式中设置为栈内唯一时,也就是android:launchMode=”singleTask”或android:launchMode=”signleTop”或singleInstance 时,会用到这个onNewIntent()方法。
当调用到onNewIntent(intent)的时候,需要在onNewIntent()中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。
-- Android5.0,在涉及用户隐私的Acitivity中(例如登录,支付等其他输入敏感信息的界面中)增加WindowManager.LayoutParams.FLAG_SECURE属性,该属性能防止屏幕被截图和录制。
-- 继承AppCompatActivity的Activity隐藏标题栏
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"//成功隐藏标题栏 />
> activity渲染xml文件
通常情况下Android需要将xml布局文件转换成GPU可以识别的绘制对象,而这些绘制对象被存放到DisplayList的数组中,当view第一次绘制的时候DisplayList被创建,view第二次绘制的时候GPU就直接从DisplayList获取绘制对象,省去了Measure,Layout的时间,但是如果我们改变了view的绘制内容那么得重新Measure,layout,DisplayList也会被重新创建,这么看来动画效果是非常消耗性能的。因为它必须经过多次重绘。
> Activity的一些属性
-- Android系统明确指定的一个Intent可由两方面属性来衡量。
· 主要属性:包括Action和Data。其中Action用于表示该Intent所表达的动作意图、Data用于表示该Action所操作的数据。
· 次要属性:包括Category、Type、Component和Extras。其中Category表示类别,Type表示数据的MIME类型,Component可用于指定特定的Intent响应者(例如指定广播接收者为某Package的某个BroadcastReceiver),Extras用于承载其他的信息。
-- Andorid规定了3项内容.
· Action:求职方支持的Intent动作(和Intent中的Action对应)。
· Category:求职方支持的Intent种类(和Intent的Category对应)。
· Data:求职方支持的Intent 数据(和Intent的Data对应,包括URI和MIME类型)。
-- IntentFilter中的Data可以包括两个内容。
· URI:完整格式为“scheme://host:port/path”,包含4个部分,scheme、host、port和path。其中host和port合起来标示URI authority,用于指明服务器的网络地址(IP加端口号)。由于URI最多可包含,4个部分,因此要根据情况相应部分做匹配检查。
· Date type:指定数据的MIME类型,要特别注意的是,URI中也可以携带数据的类型信息,所以在匹配过程中,还需要考虑URI中指定的数据类型。
-- LocalActivityManager和Instrumentation
Instrumentation (负责监控 Activity 和 AMS 的交互,所有 Activity 的本地进程到远端进程的调用转换都是其来执行)。
LocalActivityManager是Android封装的把activity转换成view对象的一个api.LocalActivityManager类是管理activity的,然后通过startActivity(String id,Intent intent)这个方法获取Window获取当前Window对象。
在android.app包下有Instrumentation这个类,这个类没有继承和实现其它的任何类,也没被其它的类继承.会在应用的任何代码执行前被实列化,用来监控系统组件与应用的交互过程,其实就是很多操作封装一下,由它来完成实现. Instrumentation另一个重要作用是提供Android组件单元测试.
每一个应用进程中只有唯一的Instrumentation, 在ActivityThread中成员变量Instrumentation mInstrumentation,通过方法public Instrumentation getInstrumentation()来获得.
-- 启动一个Activity的方式有以下几种:
(1)在应用程序中调用startActivity启动指定的Activity;
(2)在Home程序中单击一个应用图标,启动新的Activity;
(3)按“Back”键,结束当前Activity,返回到上一个Activity;
(4)长按“Home”键,显示出当前正在运行的程序列表,从中选择一个启动;
这四种启动方式的主体处理流程都会按照第一种启动方式运行,后面三种方式只是在前端消息处理上各有不同。
-- Activity的启动是一个非常复杂的过程。这里我们简单介绍一下背景知识:
1.ActivityManagerService中通过Stack和Task来管理Activity;
2.每一个Activity都属于一个Task,一个Task可能包含多个Activity,一个Stack包含多个Task;
3.ActivityStackSupervisor类负责管理所有的Stack;
-- Activity的启动过程会牵涉到:
Intent的解析;
Stack,Task的查询或创建;
Activity进程的创建;
Activity窗口的创建;
Activity的生命周期调度;
> Activity与Context的区别??
Activity、Service、Application都是Context的子类。Activity和Application都是Context的子类,Context是上下文的意思,在实际应用中它起到了管理上下文环境中各个参数和变量的作用。虽然Application和Activity都是Context的子类,但是他们维护的生命周期是不一样的,前者维护一个Activity的生命周期,所以其对应的Context只能访问该Activity,后者维护一个Application的生命周期。(App中的Context相当于Apk环境/沙箱)
在 Activity 不停的创建与销毁的过程当中,很有可能因为工作线程持有 Activity 的 View 而导致内存泄漏(因为工作线程很可能持有 View 的强引用,另外工作线程的生命周期还无法保证和 Activity 的生命周期一致,这样就容易发生内存泄漏了)。除了可能引起内存泄漏之外,在 Activity 被销毁之后,工作线程还继续更新视图是没有意义的,因为此时视图已经不在界面上显示了。
-- Android 中this(Actvitiy)、 getApplicationContext()、getApplication()之间的区别
首先Activity和Application都是Context的子类。Context从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理上下文环境中各个参数和变量的总用,方便我们可以简单的访问到各种资源。虽然Activity和Application都是Context的子类,但是他们维护的生命周期不一样。
前者维护一个Acitivity的生命周期,所以其对应的Context也只能访问该activity内的各种资源。后者则是维护一个Application的证明周期。
this(Actvitiy):代表当前,在Activity当中就是代表当前的Activity,换句话说就是Activity.this在Activity当中可以缩写为this.
getApplicationContext():生命周期是整个应用,应用摧毁,它才摧毁。
getApplication():andorid 开发中共享全局数据;
-- getContext() getActivity()的区别?
关于getContext()、getApplication()、getApplicationContext()、getActivity()的区别:
(1).getContext():获取到当前对象的上下文。
(2).getApplication():获得Application的对象
(3).getApplicationContext():获得应用程序的上下文。有且仅有一个相同的对象。生命周期随着应用程序的摧毁而销毁。就像是社会,所有的都发生在这个社会上,仅且只有一个社会。每个Activity都有自己的上下文,而整个应用只有一个上下文
(4)getActivity():获得Fragment依附的Activity对象。Fragment里边的getActivity()不推荐使用原因如下:这个方法会返回当前Fragment所附加的Activity,当Fragment生命周期结束并销毁时,getActivity()返回的是null,所以在使用时要注意判断null或者捕获空指针异常。所以只要判断getActivity()为空,就可以不再执行下面的代码,这完全不影响业务的使用。
> Android应用程序启动过程的启动过程:
一. Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
二. ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
三. Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
四. ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
五. ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
> activity几大生命周期:onCreate -> (onRestart())onStart -> onResume -> onPause -> onStop -> onDestroy。称之为entire lifetime。
Shutting Down an Activity:You can shut down an activity by calling its finish() method.
You can also shut down a separate activity that you previously started by calling finishActivity().
Therefore, you should use onPause() to write crucial persistent data (such as user edits) to storage.
onCreate : 该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,我们在创建Activity时一般都需要重写该方法,然后在该方法中做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等。
onStart : 此方法被回调时表示Activity正在启动,此时Activity已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。可以简单理解为Activity已显示而我们无法看见摆了。
onStart是activity用户可见,包括有一个activity在他上面,但没有将它完全覆盖,用户可以看到部分activity但不能与它交互。
onRestart :表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前Activity页面时,onRestart方法就会被回调。
onResume : 当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态),onResume方法与onStart的相同点是两者都表示Activity可见,只不过onStart回调时Activity还是后台无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图,我们也可以看出当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。
onPause : 此方法被回调时则表示Activity正在停止(Paused形态),一般情况下onStop方法会紧接着被回调。但通过流程图我们还可以看到一种情况是onPause方法执行后直接执行了onResume方法,这属于比较极端的现象了,这可能是用户操作使当前Activity退居后台后又迅速地再回到到当前的Activity,此时onResume方法就会被回调。当然,在onPause方法中我们可以做一些数据存储或者动画停止或者资源回收的操作,但是不能太耗时,因为这可能会影响到新的Activity的显示—onPause方法执行完成后,新Activity的onResume方法才会被执行。
onStop : 一般在onPause方法执行完成直接执行,表示Activity即将停止或者完全被覆盖(Stopped形态),此时Activity不可见,仅在后台运行。同样地,在onStop方法可以做一些资源释放的操作(不能太耗时)。
onDestroy :此时Activity正在被销毁,也是生命周期最后一个执行的方法,一般我们可以在此方法中做一些回收工作和最终的资源释放。
-- Performing stop of activity that is not resumed
是因为在Activity A 中在oncreate中启动了另一个activity B,而这个Activity A没有走完Activity的生命流程(oncreate->onstart->onstop)所以会报错。这种情况可以选择使用handler机制在oncreate中发送个message给handler启动另外一个活动。
-- Activity的生命周期,finish调用后其他生命周期还会走么?-->会走onStop() onDestroy()
当一个Activity在PAUSE时,被kill之前,它可以调用onSaveInstanceState()来保存当前activity的状态信息(在paused状态时,要被KILLED的时候)。用来保存状态信息的Bundle会同时传给两个method,即onRestoreInstanceState() and onCreate().
1、如果是用户自动按下返回键,或程序调用finish()退出程序,是不会触发onSaveInstanceState()和onRestoreInstanceState()的。
2、每次用户旋转屏幕时,您的Activity将被破坏并重新创建。当屏幕改变方向时,系统会破坏并重新创建前台Activity,因为屏幕配置已更改,您的Activity可能需要加载替代资源(例如布局)。即会执行onSaveInstanceState()和onRestoreInstanceState()的。
-- 屏幕在进行旋转后,生命周期是:销毁->创建,同时,会增加两个方法:onSaveInstanceState,onRestoreInstanceState,此时完整的生命周期是:onCreate->onStart->onResume->onPause->onSaveInstanceState->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume->Running状态。
- onSaveInstanceState与OnRestoreInstance的调用时机
在在点击home键,或者跳转其他界面的时候,都会回调用onSaveInstanceState,但是再次唤醒却不一定调用OnRestoreInstance,这是为什么呢?onSaveInstanceState与OnRestoreInstance难道不是配对使用的?在Android中,onSaveInstanceState是为了预防Activity被后台杀死的情况做的预处理,如果Activity没有被后台杀死,那么自然也就不需要进行现场的恢复,也就不会调用OnRestoreInstance,而大多数情况下,Activity不会那么快被杀死。
- onSaveInstanceState的调用时机
onSaveInstanceState函数是Android针对可能被后台杀死的Activity做的一种预防,它的执行时机在2.3之前是在onPause之前,2.3之后,放在了onStop函数之前,也就说Activity失去焦点后,可能会由于内存不足,被回收的情况下,都会去执行onSaveInstanceState。
public class AndroidTest extends Activity {
private static final String TAG = "MyNewLog";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If an instance of this activity had previously stopped, we can
// get the original text it started with.
if(null != savedInstanceState) {
int IntTest = savedInstanceState.getInt("IntTest");
String StrTest = savedInstanceState.getString("StrTest");
Log.e(TAG, "onCreate get the savedInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
}
setContentView(R.layout.main);
Log.e(TAG, "onCreate");
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save away the original text, so we still have it if the activity
// needs to be killed while paused.
savedInstanceState.putInt("IntTest", 0);
savedInstanceState.putString("StrTest", "savedInstanceState test");
super.onSaveInstanceState(savedInstanceState);
Log.e(TAG, "onSaveInstanceState");
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int IntTest = savedInstanceState.getInt("IntTest");
String StrTest = savedInstanceState.getString("StrTest");
Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
}
}
-- activity绘制
每个activity都有一个window对象,在Android中,window对象通常由一个phonewindow去实现的,phonewindow将一个DecorView设置为整个窗口的根View,DecorView作为窗口界面的顶层视图,封装了一些通用的方法,可以说,DecorView将要显示的内容都给了phonewindow,这里面所有的View监听,都是通过winsowmanagerService来接收的,通过相应的回调来OnClicListener,在显示上,他将屏幕分成了两部分,一个title一个content,看到这里,大家应该能看到一个熟悉的界面ContentView,它是一个ID为content分framelayout,activity_main.xml就是设置在这个framelayout里面。
-- Activity与Activity传递数据并回传数据;startActivityForResult() 与 setResult(),onActivityResult
1. Activity A: startActivityForResult(Intent intent, int requestCode);
2. Activity B: setResult(int resultCode, Intent data)
3. Activity A: onActivityResult(int requestCode, int resultCode, Intent data)
Activity之间数据交流(startActivityForResult , onActivityResult , setResult 的用法)- https://www.cnblogs.com/Song-double-rain/p/3269079.html
-- 两个Activity之间传递图片(Bitmap)的方法,Activity之间传递图片(Drawable,Bitmap)
Activity之间传递图片- https://www.jianshu.com/p/e7e856bd17f2
Intent来传,但是图片的大小却限定的很小,似乎只有512K还是1M。
//传递Parcelable序列化数据;bitmap存储为byte数组;或者传图片的URL
Intent intent=new Intent(MainActivity.this,TranActivity.class);
intent.putExtra("bitmap", bitmap);
startActivity(intent);
imageview=(ImageView)findViewById(R.id.trans_imageview);
Intent intent=getIntent();
if(intent!=null)
{
bitmap=intent.getParcelableExtra("bitmap");
imageview.setImageBitmap(bitmap);
}
将drawable图片转化成bitmap类型,使用bundle或Intent的extral域直接传递bitmap,这样做,在进入某些app的时候,程序居然直接崩了。
把drawable转化为bitmap,再将bitmap存储为byte数组,然后再通过Intent传递。
private byte[] bitmap2Bytes(Bitmap bm){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
在android中页面与页面之间的数据传递,我们一般都是使用Intent,但是Intent有时候也不是很好,就比如在一个Activity中传递一个图片到另一个Activity,也可以使用Intent来传,但是图片的大小却限定的很小,似乎只有512K还是1M,而如果我们想传再大一点的图片..对不起..程序就报异常了.
> AppCompatActivity与Activity
Activity 发展到3.0(大概)之后,可以使用fragment了,但是support v4 提供了1.6~3.0的fragment兼容,所以如果需要用兼容版的fragment,则需要继承support v4提供的FragmentActivity。而后一点点时间之后,3.0(大概)出现的ActionBar也被向前支持了,这次是出现在support v7里,如果需要使用兼容版的actionbar,则继承support v7提供的ActionBarActivity(它是继承FragmentActivity的)。再然后也就是去年年底到今年,5.0提供了很多很多新东西,于是support v7也更新了,出现了AppCompatActivity。
安卓全屏设置实现(基于Activity与AppCompatActivity)- http://m.blog.csdn.net/qq_29983773/article/details/73472424
AppCompatActivity默认带标题,设置全屏,继承AppCompatActivity的解决方法是用主题的形式设置全屏,在stytles文件中设置如下代码:
AppCompatActivity使用requestWindowFeature(Window.FEATURE_NO_TITLE);会报错
-- Activity实现全屏:
requestWindowature(Window.FEATURE_NO_TITLE);//隐藏标题栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//隐藏状态栏.
Android设置Activity背景为透明style- http://blog.csdn.net/mad1989/article/details/38122713/
> FragmentActivity和Activity
fragment是3.0以后的东西,为了在低版本中使用fragment就要用到android-support-v4.jar兼容包,而fragmentActivity就是这个兼容包里面的,它提供了操作fragment的一些方法,其功能跟3.0及以后的版本的Activity的功能一样。
1、FragmentActivity 继承自Activity,用来解决Android 3.0之前无法使用Fragment的问题,所以在使用的时候需要导入android-support-v4.jar兼容包,同时继承 FragmentActivity,这样在Activity中就能嵌入Fragment来实现你想要的布局效果。
2、当然Android 3.0之后你就可以直接继承自Activity,并且在其中嵌入使用Fragment。
3、获得FragmentManager的方式也不同 :Android 3.0以下:getSupportFragmentManager() ;Android 3.0以上:getFragmentManager().
活动页面继承Activity,在当前页按home键,然后点击APP logo,会进入首页页面,不会进入当前页;而活动页面继承FragmentActivity,在当前页按home键,然后点击APP logo,会进入当前页(待进一步测试)。
-- 如果你的Cursor需要在Activity的不同的生命周期方法中打开和关闭,那么一般可以这样做:
在onCreate()中打开,在onDestroy()中关闭;
在onStart() 中打开,在onStop() 中关闭;
在onResume()中打开,在onPause() 中关闭;
即要在成对的生命周期方法中打开/关闭。
> Activity和Fragment的生命周期执行顺序- https://blog.csdn.net/eyishion/article/details/54318740
Activity和Fragment生命周期变化- https://www.cnblogs.com/gzdx-tjh/p/4923331.html
- Activity和Fragment创建
Activity::onCreate;Fragment::onAttach;Fragment::onCreate;Fragment::onCreateView;Fragment::onActivityCreate;
Activity::onStart; Fragment::onSatrt;
Activity::onResume;Fragment::onResume;
- Activity和Fragment都会被销毁
Fragment::onPause;Activity::onPause;Fragment::onSaveInstanceState(保存销毁前的状态);
Fragment::onStop;Activity::onStop;
Fragment::onDestroyView;Fragment::onDestroy;Fragment::onDetach;Activity::onDestroy;
-- Fragment与Activity的生命周期之间的联系
http://www.cnblogs.com/mengdd/archive/2013/01/11/2856374.html
http://blog.csdn.net/zjclugger/article/details/10442335
当activity处于Resumed状态时,可以自由地添加和移除fragment,也即是说,只有activity在Resumed状态时,fragment的状态可以独立改变。但是,当activity离开Resumed状态,fragment的生命周期被activity控制。
-- Activity向Fragment中传值:Intent或通过调用Fragment的方法
Fragment1 fragment1 = new Fragment1();
Bundle bundle = new Bundle();
String strValue = et1.getText().toString().trim();
bundle.putString("str", strValue);
fragment1.setArguments(bundle);
//如果transaction commit()过 那么我们要重新得到transaction
transaction = manager.beginTransaction();
transaction.replace(R.id.contents, fragment1);
transaction.commit();
-- 重写Activity的onTouch() Android
Android Activity切换(跳转)时出现黑屏的解决方法- http://www.jb51.net/article/38373.htm
Android 中如何计算 App 的启动时间?- http://blog.csdn.net/wzgiceman/article/details/50607123
普通应用启动时间计算命令: adb shell am start -W com.media.painter/com.media.painter.PainterMainActivity
> 自定义Activity栈,将Activity放在栈,并设置优先级?设置Activity启动优先级?
activity管理栈- https://github.com/renxiaoys1/activitythread
自定义栈管理android的Activity- http://blog.csdn.net/muyu114/article/details/5739874/
Android:Activity统一堆栈管理(实现随时finish特定或是所有Activty)- http://blog.csdn.net/u010635353/article/details/49681659
activity管理栈,归整合优- https://www.jianshu.com/p/e6c5adcac8e0
activity栈管理的3种方式- http://blog.csdn.net/sinat_28496853/article/details/51161052
Android插件化系列第(一)篇---Hook技术之Activity的启动过程拦截- https://www.jianshu.com/p/69bfbda302df
android如何让service不被杀死-提高进程优先级- https://my.oschina.net/f839903061/blog/146709
> AppCompatActivity
AppCompatActivity设置全屏/状态栏颜色- https://blog.csdn.net/iblade/article/details/74246808