启动模式javascript
- standard:默认的启动模式,每次建立都会产生新的实例,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中
- singleTop:栈顶复用模式,若是新的activity已经位于栈顶,那么这个Activity不会被重写建立,同时它的onNewIntent(Intent intent)方法会被调用,经过此方法的参数咱们能够去除当前请求的信息,该 Activity的实例不在该栈或者不在栈顶 时,其行为同standard启动模式
- singleTask:栈内复用模式,若是栈中存在这个Activity的实例就会复用这个Activity,无论它是否位于栈顶,复用时,会将它上面的Activity所有出栈,而且会回调该实例的onNewIntent方法。
- singleInstance:全局惟一模式,具有singleTask模式的全部特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具备全局惟一性,即整个系统中就这么一个实例,因为栈内复用的特性,后续的请求均不会建立新的Activity实例,除非这个特殊的任务栈被销毁了,当复用该实例 会回调onNewIntent方法
Activity的启动过程 必须掌握的Activity启动过程html
分别调用onSaveInstanceState(Bundle outState)和
onRestoreInstanceState(Bundle outState) 2个方法保存和恢复状态。
复制代码
按Home键,再开启activity. java
- 使用这种start方式启动的Service的生命周期以下: onCreate()--->onStartCommand()(onStart()方法已过期) ---> onDestory()
- 若是服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()
- 服务中止的时候调用 onDestory()。服务只会被中止一次。
- 特色:一旦服务开启跟调用者(开启者)就没有任何关系了。 开启者退出了,开启者挂了,服务还在后台长期的运行。 开启者不能调用服务里面的方法。
- 使用这种start方式启动的Service的生命周期以下:onCreate() --->onBind()--->onunbind()--->onDestory()
- bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。 绑定者能够调用服务里面的方法
一种是使用broadcast,另外一种是使用bindService。android
//new出上边定义好的BroadcastReceiver
MyBroadCastReceiver yBroadCastReceiver = new MyBroadCastReceiver();
//实例化过滤器并设置要过滤的广播
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注册广播
myContext.registerReceiver(smsBroadCastReceiver,intentFilter,
"android.permission.RECEIVE_SMS", null);
复制代码
直接在Manifest.xml文件的节点中配置广播接收者web
<receiver android:name=".MyBroadCastReceiver">
<!-- android:priority属性是设置此接收者的优先级(从-1000到1000) -->
<intent-filter android:priority="20">
<actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
复制代码
- 第一种不是常驻型广播,也就是说广播跟随程序的生命周期。
- 第二种是常驻型,也就是说当应用程序关闭后,若是有信息广播来,程序也会被系统调用自动运行。
- 无序广播:全部的接收者都会接收事件,不能够被拦截,不能够被修改。
- 有序广播:按照优先级,一级一级的向下传递,接收者能够修改广播数据,也能够终止广播事件。
ContentProvider的基本使用方法和做用。ContentValue的使用方法,他和HashMap的区别是什么?数据库
ContentProvider 是Android系统中提供的专门用户不一样应用间进行数据共享的组件,提供了一套标准的接口用来获取以及操做数据,准许开发者把本身的应用数据根据需求开放给其余应用进行增删改查,而无须担忧直接开放数据库权限而带来的安全问题。数组
ContentValue: 存储数据封装的HashMap,提供 put、get等方法浏览器
2.性能上:
3.选用:
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。
即HTTP下加入SSL (Secure Socket Layer)层,HTTPS的安全基础是SSL,所以加密的详细内容就须要SSL。
Android使用OkHttp请求自签名的https网站 Android Https相关彻底解析 当OkHttp遇到Https HTTPS和HTTP的区别
- public boolean dispatchTouchEvent(MotionEvent ev); //用来分派event
- public boolean onInterceptTouchEvent(MotionEvent ev); //用来拦截event
- public boolean onTouchEvent(MotionEvent ev); //用来处理event
方 法 | 解析 |
---|---|
dispatchTouchEvent() | 用来分派事件。其中调用了onInterceptTouchEvent()和onTouchEvent(),通常不重写该方法,返回true则表示该事件被消费 |
onInterceptTouchEvent() | 用来拦截事件。ViewGroup类中的源码实现就是{return false;}表示不拦截该事件,事件将向下传递(传递给其子View);若手动重写该方法,使其返回true则表示拦截,事件将终止向下传递,事件由当前ViewGroup类来处理,就是调用该类的onTouchEvent()方法 |
onTouchEvent() | 用来处理事件。返回true则表示该View能处理该事件,事件将终止向上传递(传递给其父View);返回false表示不能处理,则把事件传递给其父View的onTouchEvent()方法来处理 |
Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
Android3.0以前有2种,3.0后有3种。
复制代码
注1:AnimationSet 继承自Animation,是上面四种的组合容器管理类,没有本身特有的属性,他的属性继承自Animation,因此特别注意,当咱们对set标签使用Animation的属性时会对该标签下的全部子控件都产生影响。
注2:补间动画执行以后并未改变View的真实布局属性值。切记这一点,譬如咱们在Activity中有一个Button在屏幕上方,咱们设置了平移动画移动到屏幕下方而后保持动画最后执行状态呆在屏幕下方,这时若是点击屏幕下方动画执行以后的Button是没有任何反应的,而点击原来屏幕上方没有Button的地方却响应的是点击Button的事件。
ObjectAnimator mObjectAnimator= ObjectAnimator.ofInt(view, "customerDefineAnyThingName", 0, 1).setDuration(2000);
mObjectAnimator.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
//int value = animation.getAnimatedValue(); 能够获取当前属性值
//view.postInvalidate(); 能够主动刷新
//view.setXXX(value);
//view.setXXX(value);
//......能够批量修改属性
}
});
复制代码
ObjectAnimator.ofFloat(view, "rotationY", 0.0f, 360.0f).setDuration(1000).start();
复制代码
PropertyValuesHolder a1 = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
PropertyValuesHolder a2 = PropertyValuesHolder.ofFloat("translationY", 0, viewWidth);
......
ObjectAnimator.ofPropertyValuesHolder(view, a1, a2, ......).setDuration(1000).start();
复制代码
ValueAnimator animator = ValueAnimator.ofFloat(0, mContentHeight); //定义动画
animator.setTarget(view); //设置做用目标
animator.setDuration(5000).start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation){
float value = (float) animation.getAnimatedValue();
view.setXXX(value); //必须经过这里设置属性值才有效
view.mXXX = value; //不须要setXXX属性方法
}
});
复制代码
特别注意:ValueAnimator只是动画计算管理驱动,设置了做用目标,但没有设置属性,须要经过updateListener里设置属性才会生效。
android系统中应用程序之间不能共享内存。 所以,在不一样应用程序之间交互数据(跨进程通信)就稍微麻烦一些
如调用系统通话应用
Intent callIntent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:12345678");
startActivity(callIntent);
复制代码
Content Provider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)。应用程序能够利用Content Provider完成下面的工做
虽然Content Provider也能够在同一个应用程序中被访问,但这么作并无什么意义。Content Provider存在的目的向其余应用程序共享数据和容许其余应用程序对数据进行增、删、改操做。 Android系统自己提供了不少Content Provider,例如,音频、视频、联系人信息等等。咱们能够经过这些Content Provider得到相关信息的列表。这些列表数据将以Cursor对象返回。所以,从Content Provider返回的数据是二维表的形式。
如访问系统相册
复制代码
广播是一种被动跨进程通信的方式。当某个程序向系统发送广播时,其余的应用程序只能被动地接收广播数据。这就象电台进行广播同样,听众只能被动地收听,而不能主动与电台进行沟通。例如获取手机电量信息
复制代码
一、定义:Android系统中的进程之间不能共享内存,所以,须要提供一些机制在不一样进程之间进行数据通讯。 为了使其余的应用程序也能够访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与不少其余的基于RPC的解决方案同样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。咱们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)均可以进行跨进程访问,另一个Android应用程序组件Service一样能够。所以,能够将这种能够跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
Binder是Android实现 跨进程通信(IPC)的方式,是一种虚拟的物理设备驱动,实现了IBindler 接口。
区别:
- 进程间,用户空间的数据不可共享,因此用户空间 = 不可共享空间
- 进程间,内核空间的数据可共享,因此内核空间 = 可共享空间
对比 Linux (Android基于Linux)上的其余进程通讯方式(管道、消息队列、共享内存、 信号量、Socket),Binder 机制的优势有:
![]()
做用:Handle 进行消息传递
思路:Andorid APP默认的类加载是PathClassLoader,这个只能加载本身APK的dex文件,因此咱们须要使用DexClassLoader。咱们用DexClassLoader加载外部的APK以后,经过反射获取对应的资源。
缓存层分为三层:内存层,磁盘层,网络层
public class AppSettings {
private static AppSettings sInstance;
private Context mContext;
private AppSettings(Context context) {
this.mContext = context;
//this.mContext = context.getApplicationContext();
}
public static AppSettings getInstance(Context context) {
if (sInstance == null) {
sInstance = new AppSettings(context);
}
return sInstance;
}
}
复制代码
二、静态变量致使内存泄露
public class MainActivity extends AppCompatActivity {
private static Info sInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (sInfo != null) {
sInfo = new Info(this);
}
}
}
class Info {
public Info(Activity activity) {
}
}
复制代码
Info做为Activity的静态成员,而且持有Activity的引用,可是sInfo做为静态变量,生命周期确定比Activity长。因此当Activity退出后,sInfo仍然引用了Activity,Activity不能被回收,这就致使了内存泄露。
三、非静态内部类致使内存泄露
非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期比外部类对象的生命周期长时,就会致使内存泄露。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start();
}
private void start() {
Message msg = Message.obtain();
msg.what = 1;
mHandler.sendMessage(msg);
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
// 作相应逻辑
}
}
};
}
复制代码
熟悉Handler消息机制的都知道,mHandler会做为成员变量保存在发送的消息msg中,即msg持有mHandler的引用,而mHandler是Activity的非静态内部类实例,即mHandler持有Activity的引用,那么咱们就能够理解为msg间接持有Activity的引用。msg被发送后先放到消息队列MessageQueue中,而后等待Looper的轮询处理(MessageQueue和Looper都是与线程相关联的,MessageQueue是Looper引用的成员变量,而Looper是保存在ThreadLocal中的)。那么当Activity退出后,msg可能仍然存在于消息对列MessageQueue中未处理或者正在处理,那么这样就会致使Activity没法被回收,以至发生Activity的内存泄露。
一般在Android开发中若是要使用内部类,但又要规避内存泄露,通常都会采用静态内部类+弱引用的方式。
public class MainActivity extends AppCompatActivity {
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new MyHandler(this);
start();
}
private void start() {
Message msg = Message.obtain();
msg.what = 1;
mHandler.sendMessage(msg);
}
private static class MyHandler extends Handler {
private WeakReference<MainActivity> activityWeakReference;
public MyHandler(MainActivity activity) {
activityWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = activityWeakReference.get();
if (activity != null) {
if (msg.what == 1) {
// 作相应逻辑
}
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
复制代码
非静态内部类形成内存泄露还有一种状况就是使用Thread或者AsyncTask
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
// 模拟相应耗时逻辑
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
复制代码
这种方式新建的子线程Thread和AsyncTask都是匿名内部类对象,默认就隐式的持有外部Activity的引用,致使Activity内存泄露。
四、未取消注册或回调致使内存泄露
五、Timer和TimerTask致使内存泄露
六、集合中的对象未清理形成内存泄露
若是一个对象放入到ArrayList、HashMap等集合中,这个集合就会持有该对象的引用。当咱们再也不须要这个对象时,也并无将它从集合中移除,这样只要集合还在使用(而此对象已经无用了),这个对象就形成了内存泄露。而且若是集合被静态引用的话,集合里面那些没有用的对象更会形成内存泄露了。因此在使用集合时要及时将不用的对象从集合remove,或者clear集合,以免内存泄漏。
七、资源未关闭或释放致使内存泄露
在使用IO、File流或者Sqlite、Cursor等资源时要及时关闭。这些资源在进行读写操做时一般都使用了缓冲,若是及时不关闭,这些缓冲对象就会一直被占用而得不到释放,以至发生内存泄露。所以咱们在不须要使用它们的时候就及时关闭,以便缓冲能及时获得释放,从而避免内存泄露。
八、属性动画形成内存泄露
动画一样是一个耗时任务,好比在Activity中启动了属性动画(ObjectAnimator),可是在销毁的时候,没有调用cancle方法,虽然咱们看不到动画了,可是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就形成Activity没法正常释放。所以一样要在Activity销毁的时候cancel掉属性动画,避免发生内存泄漏。
@Override
protected void onDestroy() {
super.onDestroy();
mAnimator.cancel();
}
复制代码
九、WebView形成内存泄露
关于WebView的内存泄露,由于WebView在加载网页后会长期占用内存而不能被释放,所以咱们在Activity销毁后要调用它的destory()方法来销毁它以释放内存。
@Override
protected void onDestroy() {
super.onDestroy();
// 先从父控件中移除WebView
mWebViewContainer.removeView(mWebView);
mWebView.stopLoading();
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.removeAllViews();
mWebView.destroy();
}
复制代码
十、总结
1).资源对象没关闭形成的内存泄漏 2).构造Adapter时,没有使用缓存的convertView 3).Bitmap对象不在使用时调用recycle()释放内存 4).试着使用关于application的context来替代和activity相关的context 5).注册没取消形成的内存泄漏 6).集合中对象没清理形成的内存泄漏
查找内存泄漏可使用Android Stdio 自带的Android Profiler工具,也可使用Square产品的LeadCanary.
webView.loadUrl("javascript:javacalljs()");
复制代码
二、Html
**注意:**考虑有返回值状况;Android在4.4以前并无提供直接调用js函数并获取值的方法,因此在此以前,经常使用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。
// 4.4以后 java代码时用evaluateJavascript方法调用
private void testEvaluateJavascript(WebView webView) {
webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(LOGTAG, "onReceiveValue value=" + value);
}});
}
复制代码
webView.addJavascriptInterface(MainActivity.this,"android");
复制代码
二、html
<body>
HTML 内容显示 <br/>
<h1><div id="content">内容显示</div></h1><br/>
<input type="button" value="点击调用java代码" onclick="window.android.startFunction()" /><br/>
<input type="button" value="点击调用java代码并传递参数" onclick="window.android.startFunction('http://blog.csdn.net/Leejizhou')" />
</body>
复制代码
//懒汉式
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static synchronized Singleton getSingleton() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
复制代码
//饿汉式
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton () {
}
public static Singleton getSingleton() {
return singleton;
}
}
复制代码
//double-lock
public class Singleton {
private volatile static Singleton singleton;
private Singleton() {
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized(Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
复制代码
在Android上,若是你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称做应用程序无响应(ANR:Application Not Responding)对话框。
ANR产生的根本缘由是APP阻塞了UI线程
1:UI线程尽可能只作跟UI相关的工做,但一些复杂的UI操做,仍是须要一些技巧来处理,不如你让一个Button去setText一个10M的文本,UI确定崩掉了,不过对于此类问题,分段加载貌似是最好的方法了。 2:让耗时的工做(好比数据库操做,I/O,链接网络或者别的有可能阻碍UI线程的操做)把它放入单独的线程处理。 3:尽可能用Handler来处理UIthread和别的thread之间的交互。
一、 Activity类中的getPreferences(int mode)文件自动命名为当前活动的类名。
二、 Context类中getSharedPreferences("fileName", int mode) 此方法能够指定文件名,mode同上。
三、PreferenceManager类中的getDefaultSharedPreferences(Context context)它只接收一个context参数。
文件用当前应用程序的包名和PreferenceActivity一块儿来命名。属于整个应用程序
复制代码
用户当前正在作的事情须要这个进程。若是知足下面的条件之一,一个进程就被认为是前台进程: 1).这个进程拥有一个正在与用户交互的Activity(这个Activity的onResume()方法被调用)。 2).这个进程拥有一个绑定到正在与用户交互的activity上的Service。 3).这个进程拥有一个前台运行的Service(service调用了方法startForeground()). 4).这个进程拥有一个正在执行其任何一个生命周期回调方法(onCreate(),onStart(),或onDestroy())的Service。 5).这个进程拥有正在执行其onReceive()方法的BroadcastReceiver。 一般,在任什么时候间点,只有不多的前台进程存在。它们只有在达到没法调合的矛盾时才会被杀--如内存过小而不能继续运行时。一般,到了这时,设备就达到了一个内存分页调度状态,因此须要杀一些前台进程来保证用户界面的反应.
一个进程不拥有运行于前台的组件,可是依然能影响用户所见。知足下列条件时,进程即为可见: 这个进程拥有一个不在前台但仍可见的Activity(它的onPause()方法被调用)。当一个前台activity启动一个对话框时,就出了这种状况。
一个可见进程被认为是极其重要的。而且,除非只有杀掉它才能够保证全部前台进程的运行,不然是不能动它的。 这个进程拥有一个绑定到可见activity的Service。 一个进程不在上述两种以内,但它运行着一个被startService()所启动的service。 尽管一个服务进程不直接影响用户所见,可是它们一般作一些用户关心的事情(好比播放音乐或下载数据),因此系统不到前台进程和可见进程活不下去时不会杀它。
一个进程拥有一个当前不可见的activity(activity的onStop()方法被调用)。
一个进程不拥有任何active组件。
Android中的线程池都是之间或间接经过配置ThreadPoolExecutor来实现不一样特性的线程池.Android中最多见的四类具备不一样特性的线程池分别为FixThreadPool、CachedThreadPool、SingleThreadPool、ScheduleThreadExecutor.
**FixThreadPool: **只有核心线程,而且数量固定的,也不会被回收,全部线程都活动时,由于队列没有限制大小,新任务会等待执行. 优势:更快的响应外界请求.
**SingleThreadPool:**只有一个核心线程,确保全部的任务都在同一线程中按顺序完成.所以不须要处理线程同步的问题.
**CachedThreadPool:**只有非核心线程,最大线程数很是大,全部线程都活动时,会为新任务建立新线程,不然会利用空闲线程(60s空闲时间,过了就会被回收,因此线程池中有0个线程的可能)处理任务. 优势:任何任务都会被当即执行(任务队列SynchronousQueue至关于一个空集合);比较适合执行大量的耗时较少的任务.
**ScheduleThreadExecutor:**核心线程数固定,非核心线程(闲着没活干会被当即回收)数没有限制. 优势:执行定时任务以及有固定周期的重复任务
一、计算一张图片的大小
图片占用内存的计算公式:图片高度 * 图片宽度 * 一个像素占用的内存大小.因此,计算图片占用内存大小的时候,要考虑图片所在的目录跟设备密度,这两个因素其实影响的是图片的高宽,android会对图片进行拉升跟压缩。
二、加载bitmap过程(怎样保证不产生内存溢出)
因为Android对图片使用内存有限制,如果加载几兆的大图片便内存溢出。
Bitmap会将图片的全部像素(即长x宽)加载到内存中,若是图片分辨率过大,会直接致使内存OOM,只有在BitmapFactory加载图片时使用BitmapFactory.Options对相关参数进行配置来减小加载的像素。
三、BitmapFactory.Options相关参数详解
(1).Options.inPreferredConfig值来下降内存消耗。
好比:默认值ARGB_8888改成RGB_565,节约一半内存。
(2).设置Options.inSampleSize 缩放比例,对大图片进行压缩 。
(3).设置Options.inPurgeable和inInputShareable:让系统能及时回 收内存。
A:inPurgeable:设置为True时,表示系统内存不足时能够被回 收,设置为False时,表示不能被回收。
B:inInputShareable:设置是否深拷贝,与inPurgeable结合使用,inPurgeable为false时,该参数无心义。
(4).使用decodeStream代替其余方法。
decodeResource,setImageResource,setImageBitmap等方法
复制代码
**LRUCache算法:**内部存在一个LinkedHashMap和maxSize,把最近使用的对象用强引用存储在 LinkedHashMap中,给出来put和get方法,每次put图片时计算缓存中全部图片总大小,跟maxSize进行比较,大于maxSize,就将最久添加的图片移除;反之小于maxSize就添加进来。(400行代码不到...)
六、layout、Merge、ViewStub的做用。
merge: 它能够删减多余的层级,优化UI。例如你的主布局文件是垂直布局,引入了一个垂直布局的include,这是若是include布局使用的LinearLayout就没意义了,使用的话反而减慢你的UI表现。这时可使用标签优化。
ViewStub: 标签最大的优势是当你须要时才会加载,使用他并不会影响UI初始化时的性能。各类不经常使用的布局想进度条、显示错误消息等可使用标签,以减小内存使用量,加快渲染速度。是一个不可见的,大小为0的View。