1、四大组件

【1】activity    4种启动模式  
android:launchMode="singleInstance"/"singleTop"/"singleTask"/"standard"
standard 普通的开启模式:按开启的顺序入栈,出栈
singleTask 整个栈里只能有一个实例  特点: 当再次调用他他会把他上面的activity全部销毁,他到达栈顶。
singleTop 栈里可以有多个实例,但栈顶只能有一个实例 
singleInstance 自己开辟一个单独的栈 并且栈里面只有一个实例 整个栈里只有一个activity
如果已经存在了一个栈,并存在相同的实例,那么就不会再继续创建栈了,而是复用这个已经存在的栈和实例。经验证确实是栈里面只有一个activity。
【2】四大组件都不能进行耗时操作,执行耗时操作必须开子线程。
【3】可以为四大组件单独开一个进程
【4】进程的lifecycle
foregound Process 一个activity执行了并处于 onResume状态 broadcastReceiver正在执行
onReceive方法 service正在执行生命周期方法,调用startforeground,绑定的activity正在和用户交互。
visible process
activity执行onpause 处于可见不可操作的状态 如果service单独开启一个process 他绑定的
activity处于onpause状态 该process处于visiable process
service process 
应用ui不可见,后台只跑着一个service 后台播放音乐 执行联网下载
background process 后台有activity执行onstop 处于不可见不可操作转态 处于后台进程的应用很多,采用LRU算法决定处于后台进程的那个应用被干掉,最近最少使用最先被杀死
empty process  没有任何组件在运行 下次启动的时候提高启动的时间
【5】activity lifecycle
If an activity is paused or stopped, the system can drop it from memory either by asking it tofinish (calling its finish() method), or simply killing its
process.
如果一个activity处于onPause或onStop状态 系统回收他两种方式 调用他的finish() 或直接杀掉进程
The visible lifetime of an activity happens between the call to onStart() and the call to onStop().
The foreground lifetime of an activity happens between the call to onResume() and the call to onPause().
onDestoty()
it could be called either because the activity is finishing (someone called finish() on it), or because the system is temporarily destroying thisinstance of the activity to save space.  finish()走的是onDestory().
【6】thread-safe
如果同一时间有多个线程调用同一个对象的方法,就会出现thread-unsafe
【7】UI thread and work thread 
应用的进程里 除了 ui thread  其他用于执行耗时操作的线程都是 work thread 
【8】activity屏幕方向切换走的生命周期方法
切屏 onDestory() 然后立刻走onCreate()
如何处理重启的问题呢?
方式一:针对数据较少的情况
@override onSavaInstanceSatate() 在他里面做保存工作 
切屏走onDetory()之前 系统自动调用 onSavaInstanceState()
重新走onCreate() 在onCreate()或onRestoreInstanceState()里再取出保存的状态
方式二:针对大数据的情况
To retain an object during a runtime configuration change:
  1. Override the onRetainNonConfigurationInstance() method to return the object you would like to retain.重写
  2. When your activity is created again, call getLastNonConfigurationInstance() to recover your object.自己手动调用
@override onRetainNonConfigrationInstance() 返回一个object 用于保存状态 不能返回和上下文相关的对象 否则会造成内存泄露
在onStop()和onDestory()之间调用
在onCreate()方法里调用、getLastNonConfigurationInstance() 返回之前保存的对象
handling the configration change by yourself
自己处理屏幕的切换事件,系统就不重启activity了,但系统会发广播,通知你屏幕有变化
重写onConfigrationChanged()处理屏幕的切换事件。
To declare that your activity handles a configuration change, edit the
 appropriate <activity> element in your manifest file to include the 
android:configChanges attribute with a value that represents the configuration you want to handle.

注意:
Note: If your application targets API level 13 or higher (as declared by the 
minSdkVersion and targetSdkVersion attributes), then you should also declare the "screenSize" configuration, because it also changes when a device switches between portrait and landscape orientations.
例如:屏幕虽然切换,但是他走onDestory()和onCreate(),而是维护原来的转态继续运行,
只是当切换屏幕的时候,onConfigrationChanged()会被调用
api level >= 13
orientation|screenSize 必须成对出现
  
    
<activity
android:name=".MainActivity" android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
 
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
api level < 13
<activity android:name=".MyActivity"android:configChanges="orientation|keyboardHidden"android:label="@string/app_name">
不管API level 为啥,都要走onConfigrationChanged().
Now, when one of these configurations change, MyActivity does not restart.
Instead, the MyActivity receives a call to onConfigurationChanged().
@Override
public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);// Checks the orientation of the screenif (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();}
}
 
1.2  startService()和bindService()深入理解
混合开启开启的是同一个service对象,
unbindService(sc);//只是取消service和当前activity的绑定,并没有关闭service
stopService(intent);//彻底关闭service
下面流程写的非常详细:


1.3 为啥要配置category呢?
Activity暴露隐式意图必须配置  category节点 为了区别于其他的Activity
通过action,category 和 data 的组合,实现多种匹配方法来启动Activity。
Intent的Action、Category属性都是一个普通的字符串,其中Action代表该Intent所要完成的一个抽象“动作“,而Category则用于为Action增加额外的附加类别信息。通常Action属性会与Category属性结合使用。
  • 一个Intent对象最多只能包含一个Action属性,程序可调用Intent的setAction(String str)方法来设置Action属性值
  • 一个Intent对象可以包含多个Category属性,程序可调用Intent的addCategory(String str)方法来为Category属性
  • 当程序创建Intent时,该Intent默认启动Category属性值为Intent.CATEGORY_DEFAULT常量(常量值为android.intent.category.DEFAULT)的组件
对于Activity  如果你没有配置category属性值  那么隐式意图会自动添加
< category  android :name= "android.intent.category.DEFAULT"  />
由于你没在清单文件配置该category,intent filter不匹配,找不到activity 报错。
  • 对于Service  通过隐式意图开启服务,并不需要category。
<action  
<category   区别 限定
<data            
1.4 contentProvider

指定row
上述代码在4.4以下都可以实现写入短信的功能,而5.0上就无法写入,原因是: 从5.0开始,默认短信应用外的软件不能以写入短信 数据库 的形式发短信! 
!--属性依次为:全限定类名,用于匹配的URI,是否共享数据 --> <provider android:name="com.jay.example.bean.NameContentProvider"android:authorities="com.jay.example.providers.myprovider"android:exported="true" />
1.5 BroadcastReceiver
Android 4.3以上的版本,是允许将程序安装到SD卡上的,假如你的程序是安装在SD上 的,就会收不到开机广播,
不要在广播里添加过多逻辑或者进行任何耗时操作,因为在广播中是不允许开辟线程的,
 当onReceiver( )方法运行较长时间(超过10秒)还没有结束的话,那么程序会报错(ANR), 
广播更多的时候扮演的是一个打开其他组件的角色,比如启动Service,Notification提示, Activity等!
全局广播!这同样意味着我们APP发出的广播,其他APP都会接收到, 或者其他APP发送的广播,我们的APP也同样会接收到,这样容易引起一些安全性的问题!而  Android 中给我们提供了本地广播的机制,使用该机制发出的广播只会在APP内部传播,而且 广播接收者也只能收到本应用发出的广播!
本地广播无法通过静态注册方式来接受,相比起系统全局广播更加高效 
在Android 4.3以上的版本,允许我们将应用安装在SD上,我们都知道是系统开机 间隔一小段时间后,才装载SD卡的,这样我们的应用就可能监听不到这个广播了! 所以我们需要既监听开机广播又监听SD卡挂载广播!
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
<intent-filter>
<action android:name="ANDROID.INTENT.ACTION.MEDIA_MOUNTED"/>
<action android:name="ANDROID.INTENT.ACTION.MEDIA_UNMOUNTED"/>
<data android:scheme="file"/>
</intent-filter>
</receiver>
2、进程间通信专题  ipc :interprocess communication (IPC) 进程间通信 实现2个不同应用的通信。
【1】比如通过aidl 可以实现把当前应用 service里的方法暴露给其他应用调用  
aidl (android interface definition language)是一门专门的语言,用来实现不同应用之间的通信。
aidl  针对service的进程间通信;android studio提供了更为简洁方便的方法。
http://blog.csdn.net/lmj623565791/article/details/38461079

Android offers a mechanism for interprocess communication (IPC) using remote procedure calls (RPCs), in

android通过rpc来实现ipc

which a method is called by an activity or other application component, but executed remotely (in another

远程的方法被本地activity调用或其他应用的组件调用

process), with any result returned back to the caller. This entails decomposing a method call and its data to a

方法在远程执行 并把执行的结果返回给调用者             这其中涉及到方法是如何调用的,数据是如何传递的

level the operating system can understand,

只有操作系统能够明白

Android provides all the code to perform these IPC transactions, so you can focus on defining and

这其中的代码都有android系统来完成                                                  你的关注点在如何定义接口

implementing the RPC programming interface.

和如何远程调用

To perform IPC, your application must bind to a service, using bindService().

为了执行ipc,你的应用必须绑定bindService()

通过rpc(remote procedure call)这种方式 采用aidl语言 来实现 ipc(interprocess conmmucation)。
For example, if your application starts the activity in the camera application that captures a photo, that activity runs
别的应用开启你应用的服务  该服务运行在你的应用的进程里  通过其他应用把你的应用运行了起来 
in the process that belongs to the camera application, not in your application's process. 
虽然是其他应用调起的你的应用   但是 不同应用及其组件活在各自的进程里。
your application cannot directly activate a component from another application. The Android system, however, 
一个应用不可能直接激活另外一个应用   
can. So, to activate a component in another application, you must deliver a message to the system that specifies 
一个应用激活另外一个应用 是通过 向系统发送意图   系统根据意图  打开相应的其他应用的组件
your intent to start a particular component. The system then activates the component for you.
【2】比如不同应用之间通过隐式意图 开启activity并传递数据 :我试验了,通过其他应用暴露的隐式意图,你可以用intent打开他,并向他传递数据。
【3】比如系统应用和普通应用之间通过 广播接收者 发一个广播,通过intent传递数据
【4】还可以共享内存实现进程间通信ipc
2.1 数据库是私有的 但是我们通过ContentProvider我们可以调用其他应用的数据库。
这么说来4大组件都提供了进程间通信。
3、android性能优化方案
用IntentService代替Service开启服务,因为会自己开一个线程,不影响主线程。
http://blog.csdn.net/luoyanglizi/article/details/51586437
4:签名和包名

一、谨慎选择包名

包名 (Package Name) 就相当于一款应用在户口本上登记的名字,是系统用来区分不同应用的字段。重复的包名会被认为是同一款应用,不能同时安装在一个系统里。一般来说,包名建议使用域名反序。比如豌豆荚的网站域名是 www.wandoujia.com,那么豌豆荚的一系列 Android 应用的包名就是 com.wandoujia.***。这种约定俗成的办法可以最大程度地避免“撞名”的事故。

案例一

某个手机 ERP 客户端的开发者,在开发应用时使用了 Adobe 的工具,同时也参考了 Adobe 的官方教程,从而将应用命名为 air.Main 这样的通用包名,跟另一个游戏重名了。于是,在升级和洗白白的过程中就都产生了混乱……所以取名要慎重啊!

案例二

还 有个开发者,不知为何给几个不同的应用都使用了同一个包名。于是“com.hexin.qs.app.android”这个包名,对应了“申国万银证 券”、“中信建投手机证券”、“联讯证券手机炒股”等好几个完全不同的应用。带来的后果就是,用户不能在手机上同时安装这几个应用,而且在升级过程中也容 易从一个应用升级到另一个应用上。所以,不能给好几个孩子取同一个名字啊!

二、一款应用只应该有一个签名

签名文件就相当于开发者的“身份证”,我们平时生活中应该只有一张身份证,那么在手机里也一样,签名也应该是唯一的。而且因为签名的加密机制,使复制和伪造签名变得几乎不可能,所以“豌豆洗白白”也是将签名作为判断是否官方版的最主要标准之一。
如 果一个应用使用了不同的签名,那么对于用户来说,可能会造成应用无法升级,因为 Android 系统会在升级应用的过程中比对签名,不同的签名无法升级。如果用户选择强制升级的话,因为签名不同,所以需要先卸载旧版再安装新版,那么之前存在本地的应 用数据、游戏记录等也会直接丢失。

案例一

就好像我们会不小心弄丢身份证,开发者也会不小心弄丢签名文件。我们曾遇到过四五例类似的例子,开发者找上门来说要求更换签名,原来是因为工程师离职把签名文件带走了,老板要不回来了,只好把原来的签名也全都改一遍。所以签名文件要保管好啊!

案例二

我 们曾经统计过,网游“我叫 MT”在各大市场上一共有 48 种不同的签名。据“我叫 MT”的开发者说,他们是通过不同的签名来区分不同的渠道的,而一共放出过多少种签名难以统计。这么多个不同的签名文件,除了自己管理起来非常麻烦之外, 也给用户的升级过程带来了困扰,一不小心升级到了不同签名的版本上,游戏记录就全部丢失了。
Android 签名机制的目的是为了检验应用是否被人更改过,而不是为了让你区分渠道的。那么正常来说应该用什么方法来区分渠道呢?请看下一条。

三、使用 xml 配置文件来区分渠道

一般来说,我们在 Android manifest 文件中使用 meta-data 来区分渠道。例如:

1
<meta-data android:name= "CHANNEL" android:value= "wandoujia" />

每次正式打包完成后,修改 android:value,再重新打包即可生成一个新的渠道包,所以:

不要再用签名来区分渠道了!

四、正确填写版本号在 Android 应用中,有两个参数与版本号相关。其中,version Name 表示版本名称,是字符串,version Code 表示版本号,是整型数字。一般来说,用户直观看到的是 version Name,所以这里应该填写形似“4.15.1”这样的版本号。而真正用来判断新版本旧版本的参数是 version Code。在应用发布第一个版本的时候,version Code 应该填 1,然后每次发布的时候都递增,这样才是以规范的格式告诉各大市场你的应用的更新程度。有的开发者在 version Code 上非常随意,这个版本发布的时候碰上结婚纪念日,于是用老婆的生日当 version Code;下个版本发布的时候运气不太好,于是用自己的幸运数字当作 version Code……这样在用户看来的结果就是,明明从官网安装了最新的 2.2.0 版本,可是各大市场却提醒“升级到 2.1.3 版本”,越升级版本号越小了。以上四件小事,虽然都比较琐碎,而且没什么技术含量,但却是很多入门的 Android 开发者容易忽略的问题。希望本文能帮助广大开发者,在写出好应用的同时,避免这些“坑”给应用带来不必要的损失。

来源: http://www.cnblogs.com/smilefortoday/p/4022144.html
5:activity配置隐式意图
必须指定 action和category
   
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.bilibili.secondActivity"/>
<!--必须指定category-->
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

6:主线程和子线程?+handler消息机制?
线程之间第独立的 主线程(UI线程) 和 子线程是独立运行的  他们之间通过handler传递消息。
关于界面所有ui的处理全部都在主线程里操作
四大组件默认工作在同一线程里(主线程);只能在线程更新ui;Toast属于更新ui的范畴,故不能在子线程或其他线程更新ui。
如果主线程被阻塞超过5秒钟,系统就会报ANR(application not response)
如何避免ANR,在主线程里开子线程,执行耗时操作。
7:Android 内存优化+性能优化?
内存优化:控制内存占用空间大小 防止oom
性能优化:省电 缩短图片加载时间 缩短获取网络数据时间  提高流畅度 
【1】优化常用控件 
比如listView
复用convertView(内存优化)  构建viewHolder(性能优化)  分批加载数据 异步加载数据 构建LRUCache 使用LRUDiskCache
【2】性能优化
UI : 减少不必要的子控件 降低层级
代码 : 
8:线程
Thread.currentThread().getName();可以获取任意线程的名称
线程调度 抢占式 getPriority() setPriority(int priority)
线程退出 run()代码执行完毕  手动调用stop()
线程池 jdk5.0 以来使用 Executors 工厂类来产生线程池 
ExecutorService 对象表示线程池
线程池 框架
Executors 
   ExecutorService  线程池
         ThreadPoolExecutor
         SchedualThreadPoolExecutor
构建线程对象
    Runable 
    Callable 
线程池实例(单例)把线程对象提交给线程池submit(thread)/execute(thread) 系统自动执行线程实例
创建线程池对象 
创建runnable对象
线程池对象调用submit()或execute()把任务提交到线程池,开始执行线程。
  
    
ExecutorService executorService = Executors.newFixedThreadPool(6);
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
 
executorService.submit(runnable);/executorService.execute(runnable);

http://blog.csdn.net/lpjishu/article/details/53366175
9:单位换算
8bit = 1byte
1024byte = 1 kb
1024kb = 1Mb
1024Mb = 1G
10: LRUCache 与 LRUDiskCache
http://blog.csdn.net/sinyu890807/article/details/28863651 郭霖
LRUDiskCache 虽然api里没有,但得到了谷歌的官方认可 
其实DiskLruCache并没有限制数据的缓存位置,可以自由地进行设定,但是通常情况下多数应用程序都会将缓存的位置选择为 /sdcard/Android/data/<application package>/cache 这个路径。选择在这个位置有两点好处:第一,这是存储在SD卡上的,因此即使缓存再多的数据也不会对手机的内置存储空间有任何影响,只要SD卡空间足够就行。第二,这个路径被Android系统认定为应用程序的缓存路径,当程序被卸载的时候,这里的数据也会一起被清除掉,这样就不会出现删除程序之后手机上还有很多残留数据的问题。
权限!!!
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
11:路径分割符的区分
LogUtil.logi(this.getClass(),File.separator);// "/"
LogUtil.logi(this.getClass(),File.pathSeparator);// ":"


12:okHttp的用法
okHttp的强大之处
 它处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。

如果你的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP,此外OkHttp还处理了代理服务器问题和SSL握手失败问题。 
首先介绍下OkHttp的简单使用,主要包含:

  • 同步/异步get请求
  • 同步/异步post请求
  • 基于Http的文件上传
  • 文件下载
  • 加载图片
  • 支持请求回调,直接返回对象、对象集合
  • 支持session的保持
okHttp框架作用有三:
【1】网络请求
【2】上传
【3】下载
【1】网络强求
okHttp框架解析  http://blog.csdn.net/huaxun66/article/details/52613439?locationNum=2&fps=1
post与get不同的就是要创建RequestBody并传进Request中,同样onResponse回调不是在UI线程。
http请求方式 : get、post 最常用 
其他请求方式 patch、put 
其中okHttp除了支持 get/post请求之外还支持其他请求方式
okHttp自带缓存机制,可以对请求的数据进行磁盘缓存 Okhttp已经内置了缓存,默认是不使用的,如果想使用缓存我们需要手动设置
在okHttpClient构造时设置缓存路径
构造Request实例时配置缓存策略
http://blog.csdn.net/u012702547/article/details/53143322?locationNum=8&fps=1

创建带缓存的okHttp实例 ,构造缓存路径
一般磁盘缓存都是放在和diskLruCache缓存一样的sd卡
   
创建请求Request实例 配合缓存策略
get请求
   
同步请求,需要自己开线程
   
     
 
//[1]以同步方式请求网络,需要我们自己开子线
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
try {
 
Response response = okHttpClient.newCall(request).execute();
 
if (response.isSuccessful()) {
callback.onSuccess(response.body().bytes());
} else {
callback.onFail(response.message());
Toast.makeText(context, "请求失败", Toast.LENGTH_SHORT).show();
}
 
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "请求失败", Toast.LENGTH_SHORT).show();
}
 
}
});

     
 
//在request里构建cacheControl
CacheControl cc = new CacheControl.Builder()
// .noCache()//不使用缓存,只走网络
// .noStore()//不使用缓存,但也不保存缓存数据
// .maxAge(5,TimeUnit.SECONDS)//设置最大失效时间,超过这个时间失效,失效则不用
.maxStale(5,TimeUnit.SECONDS)//设置最大失效时间,超过这个时间失效,失效则不用
// .onlyIfCached()//只使用缓存
// .minFresh(5,TimeUnit.SECONDS)//设置最小有效时间,小于5s失效,大于5s有效,失效则不用
.build();
 
 
 
//[01]get请求,请求参数要放在url里
Request request = new Request.Builder()
.addHeader("header1", "value1")
.addHeader("header2", "value2")
.url(url)
.cacheControl(cc)//缓存策略
.tag(NetUtil.class)
.build();

配置缓存策略可以不用单独实例化一个CacheControl对象 可以使用CacheControl的常量来代替创建一个CacheControl实例
      
Request request1 = new Request.Builder()
// .cacheControl(CacheControl.FORCE_CACHE)//强制使用网络
.cacheControl(CacheControl.FORCE_NETWORK)//强制使用缓存
.build();

post请求
      
RequestBody okRequestBody = new FormBody.Builder()
.add("body", getRequestJson(requestParams))
.build();
 
request = new Request.Builder()
.addHeader("user-agent", "xxxxx")
.addHeader("accept", "yyyy")
.url(url)
.post(okRequestBody)
.build();

     
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(2000, TimeUnit.MILLISECONDS)
.cache(new Cache(new File(CachePathUtil.externalCacheFile(context)+
File.separator+"net"),
10*1024*1024))//第二个参数表示缓存区的大小为10M,
// 当缓存区的数据大小超过10M的时候会自动删除已缓存的数据
.build();

异步请求,okHttp内部自己开线程
需要注意的是onResponse回调并不是在UI线程。 
   
//[2]异步线程请求,okHttp内部开子线程
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(context, "请求失败", Toast.LENGTH_SHORT).show();
callback.onFail(e.getMessage());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
callback.onSuccess(response.body().bytes());
}
});

一般情况下我们只需要配置缓存路径就可以了,并不需要配置缓存策略 
配置了cache之后,当我们请求过一次数据之后,然后关闭掉网络,这个时候再去请求网络数据,这个时候OkHttp会自动从本地缓存中重新加载数据。
okHttp官方中文教程
http://blog.csdn.net/jackingzheng/article/details/51778793?locationNum=14&fps=1
一般一个应用只有一个okHttpClient实例。如果有多个,缓存目录要和其他的实例的缓存目录不同;否则,不同的实例同时访问相同的缓存目录会相互踩踏,导致程序崩溃。
可是很多时候我们还有许多其他的需求,那么这些需求我们可以在构造Request的时候通过CacheControl来进行进一步的配置。
在构造Request的时候,我们可以配置CacheControl,配置有两种方式,一种是构造CacheControl,还有一种是直接使用CacheControl中的常量,
noCache :不使用缓存,全部走网络 no Store : 不使用缓存,也不存储缓存onlyIfCached : 只使用缓存maxAge :设置最大失效时间,失效则不使用maxStale :设置最大失效时间,失效则不使用,超过这个时间就无效了minFresh :设置最小有效时间,失效则不使用,只有大于这个时间才有效FORCE_NETWORK : 强制走网络FORCE_CACHE :强制走缓存
我的目的是为了既能够请求网络  又能够灵活的缓存 
okHttpUtils  封装可okHttp的工具框架
http://blog.csdn.net/huaxun66/article/details/52613439?locationNum=2&fps=1
服务器支持缓存?所谓的服务器支持不支持缓存,其实说白了就是响应头里有没有cache-age这个字段
如果有,那就说服务器支持 缓存;否则,不支持。

如果服务器的响应头里没有cache-age字段,我们通过Interceptor拦截响应,并在客户端强行添加一个cache-age字段,并指定值。这时就能达到缓存的目的。

完整版
   
//Retrofit、Picasso等配合OkHttp使用的框架
public static <T> void getDataFromNet(final Context context,
String url,
Map<String, Object> requestParams,
final ReqCallback callback) {
 
 
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(2000, TimeUnit.MILLISECONDS)
.writeTimeout(2,TimeUnit.MINUTES)
.readTimeout(2,TimeUnit.MINUTES)
// .addInterceptor(new MyIntercaptor())//强行修改request和response头
.cache(new Cache(new File(CachePathUtil.externalCacheFile(context) +
File.separator + "net"),
10 * 1024 * 1024))//第二个参数表示缓存区的大小为10M,
// 当缓存区的数据大小超过10M的时候会自动删除已缓存的数据
.build();
}
 
String requestJson = getRequestJson(requestParams);
// RequestBody requestBody = RequestBody.create(MediaType.parse("json"), requestJson);
 
//abstract class RequestBody
// FormBody(表单) extends RequestBody
//MultipartBody extends RequestBody
 
FormBody requestBody = new FormBody.Builder()
.add("data",requestJson)
.build();
 
// MultipartBody multipartBody = new MultipartBody.Builder()
// .build();
 
 
//告诉okHttp缓存的有效期,和响应头的cache-control或者是interceptor的作用是一样的。所以4选一
CacheControl cc = new CacheControl.Builder()
.maxAge(5, TimeUnit.MINUTES)//5分钟之内的有效
.build();
 
Request request = new Request.Builder()
.url(url)
.tag("tag1")
// .cacheControl(CacheControl.FORCE_NETWORK)
.cacheControl(cc)
.post(requestBody)
.build();
 
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
 
}
 
@Override
public void onResponse(Call call, Response response) throws IOException {
 
}
});
 
 
}
 
//响应头里没有cache-control,我们就强行加上;否则,就不需要用Interceptor实例了
private static class MyIntercaptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
return response.newBuilder()
.removeHeader("Pragma")
.removeHeader("Cache-control")
.header("Cache-control","max-age="+3600*24*30)
.build();
}
}

【2】上传
上传文件本身也是一个POST请求,首先定义上传文件类型:
【3】下载
13 Https/http
http://blog.csdn.net/lmj623565791/article/details/48129405  https+okHttp 鸿祥
【1】编码,签名,加密
编码:urlEncoder/urlDecoder(支持特殊字符(中文等)的网络传输) 
base64(解决不可打印字符在网络中传输)
签名:md5,sha1 标识数据 不可逆
加密:RSA,DES,AES 加密数据(“明文”变“密文”) 可逆
【2】certificate  证书  authority 权威机构
“证书”洋文也叫“digital certificate”或“public key certificate”  公司的“公章”

它是用来证明某某东西确实是某某东西的东西(是不是像绕口令?)。通俗地说,证书就好比例子里面的公章。通过公章,可以证明该介绍信确实是对应的公司发出的。

  理论上,人人都可以找个证书工具,自己做一个证书。那如何防止坏人自己制作证书出来骗人捏?请看后续 CA 的介绍。

CA是Certificate Authority的缩写,也叫“证书授权中心”。
 它是负责管理和签发证书的第三方机构,就好比例子里面的中介——C 公司。一般来说,CA必须是所有行业和所有公众都信任的、认可的。因此它必须具有足够的权威性。就好比A、B两公司都必须信任C公司,才会找 C 公司作为公章的中介。
CA 证书,顾名思义,就是CA颁发的证书。
【3】SSL协议  Secure Sockets Layer 安全套接层
TLS协议 Transport Layer Security 传输层安全协议
事实上  SSL = TLS
为啥要发明 SSL 这个协议捏?因为原先互联网上使用的 HTTP 协议是明文的,存在很多缺点——比如传输内容会被偷窥(嗅探)和篡改。发明 SSL 协议,就是为了解决这些问题。
到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是“Transport Layer Security”的缩写),中文叫做“传输层安全协议”。
很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。
【4】  “HTTPS”是啥意思?
解释完 HTTP 和 SSL/TLS,现在就可以来解释 HTTPS 啦。咱们通常所说的 HTTPS 协议,说白了就是“HTTP 协议”和“SSL/TLS 协议”的组合。你可以把 HTTPS 大致理解为——“HTTP over SSL”或“HTTP over TLS”(反正 SSL 和 TLS 差不多)。
加密机制+证书机制: 在正确的站点上发送加密的请求。(证书用来保证站点正确;加密机制保证“密文”传输)
14 泛型方法的使用
public <T> Call getAsynHttp (String url, final ReqCallBack<T> callBack)
15 获取File最后一次被修改的事件
long modifiedTime = new File("path").lastModified();
16 sqlite数据库
数据库基本的操作 开源框架使用
17 混淆 jks
打包生成apk  代码混淆 对apk签名

android-基础知识解析相关推荐

  1. 100天精通Andriod逆向——第2天:Android基础知识和jadx的使用

    目录 一.Android基础知识介绍 1.1 Android 历史版本 1.2 apk 包文件结构 1.3 Android系统目录介绍 二.jadx的使用 2.1 jadx 的简介 2.2 jadx ...

  2. Android基础知识——完善

    首页 下载App × Android基础知识--完善 布鲁马 2016.05.17 10:29* 字数 5478 阅读 2672评论 1喜欢 38 疯狂Android摘要,Android基础知识好乱好 ...

  3. android基础知识

    技术型男 随笔 - 20, 文章 - 0, 评论 - 4, 引用 - 0 android基础知识 1. 前言 1.1. 什么是3G.4G Ÿ 第三代移动通信技术(3rd - Generation),速 ...

  4. Android基础知识(二十一):Android五大存储之文件存储、Content Provider存储和网络存储

    Android基础知识(二十一):Android五大存储之文件存储.Content Provider存储和网络存储 一.Android存储--持久化技术 数据持久化是指将那些内存中的瞬时数据保存到存储 ...

  5. Android基础知识巩固系列 Android之四大组件——ContentProvider(内容提供者)

    因为最近要面试,于是打算整理整理一下Android的基础知识,由于之前本人已经学习过大概的Android基础知识,这里主要讲这四大组件.五大存储.六大布局.网络请求等这些内容,其他一些等有时间再整理, ...

  6. Android基础知识:在UI线程中运行代码

    本文翻译自:Android basics: running code in the UI thread In the viewpoint of running code in the UI threa ...

  7. Android基础知识(二十):Notification、提醒式通知(横幅)踩坑与通知界面设置跳转

    Android基础知识(二十):Notification.提醒式通知(横幅)踩坑与通知界面设置跳转 一.Notification通知与基本用法 通知Notification是Android系统中比较有 ...

  8. Android基础知识【项目实训-实现二级导航“今日活动”及读取数据库】【5】

    [该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材] [项目题目]:校园订餐App设计 ...

  9. Android 基础知识+app测试权限问题

    Android 基础知识(权限篇)** 前言 ​ Android是一个开源的,基于Linux的移动设备操作系统,主要用于移动设备,如智能手机和平板电脑.Android是由谷歌及其他公司带领的开放手机联 ...

  10. 捷联惯导基础知识解析之五(低成本姿态航向参考系统)

    陀螺仪精度0.1°/s:加速度计精度5mg:主要指零偏重复性! 一.简化的惯导算法 1.姿态更新 陀螺仪输出直接进行积分,得到角增量: 2.速度更新: 在导航系下,完整的速度微分方程,如下: 其中,在 ...

最新文章

  1. 了解下C# 类型转换
  2. iOS程序启动画面的制作
  3. 喜提 Go Contributor
  4. Bootstrap3 栅格系统-栅格参数
  5. How to get list of all public urls which are using BSP UI technology
  6. Java面向对象(20)--接口
  7. C#中IEnumerableT.Distinct()将指定实体类对象用Lambda表达式实现多条件去重
  8. PCL学习笔记02:在ROS下建立编译链接PCL模块
  9. POJ3264——Balanced Lineup(线段树)
  10. 理财非保本浮动收益型什么意思?
  11. java 23种设计模式学习。
  12. trueOS能装linux软件,GhostBSD 19.09 发布,使用来自TrueOS软件包
  13. TI公司CC系列的各种芯片的区别 CC2430 CC1100
  14. tauri打包慢:解决tauri的打包慢以及超时的方法
  15. 方法重写的一大两小两同
  16. iOS系统 查看设备序列号 获取UDID
  17. Python 数据分析 —— Numpy
  18. Linux查看系统信息命令总结
  19. 苹果AR/VR设备或定价2000美元 或命名Apple Vision
  20. wap手机广告形式有哪些形式——手机站点广告代码

热门文章

  1. linux 下切换集成显卡和独立显卡,禁用独显,解决发热问题
  2. 聊聊 Kafka: Kafka 为啥这么快?
  3. Python解题 - CSDN周赛第32期 - 运输石油(三维背包)
  4. java socket telnet_使用java简单模拟ping和telnet的实现
  5. 计算机教育专业委员会开会,2017全国高校计算机教育大会在并召开
  6. 鸿蒙科学实验课,科学小实验 点亮大梦想-长春市第五十二中学开封校区开展科学实验课活动...
  7. 字符串的相关操作,例子以及应用
  8. 连云港千卓贸易有限公司
  9. 用命令行无法运行PostgreSQL命令的问题
  10. Event-----事件类型:基本类型