欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android网络框架的优缺点、图片加载框架等基础知识讲解

程序员文章站 2023-09-29 17:30:23
一:网络框架的优缺点 1.volley 优点: (1)自动调度网络请求; (2)高并发网络连接; (3)通过标准的 http cache coherence(高速缓存一致性)缓存磁盘和内存透明的响应...

一:网络框架的优缺点

1.volley

优点:

(1)自动调度网络请求;

(2)高并发网络连接;

(3)通过标准的 http cache coherence(高速缓存一致性)缓存磁盘和内存透明的响应;

(4)支持指定请求的优先级( 请求队列的优先级排序);

(5) 提供多样的取消机制:网络请求 cancel 机制,我们可以取消单个请求,或者指定取消请求队列中的一个区域;

(6)框架容易被定制,例如,定制重试或者回退功能;

(7)包含了调试与追踪工具;

(8)默认 android2.3 及以上基于 httpurlconnection,2.3 以下使用基于 httpclient

(9)提供简便的图片加载工具(其实图片的加载才是我们最为看重的功能)

缺点:

(1)不能下载文件:这也是它最致命的地方

官网或相关地址:

volley 的 github 地址:https://github.com/mcxiaoke/android-volley;

google i/o 2013 – volley: easy, fast networking for android:https://www.youtube.com/watchv=yhv8l9f44qo&feature=player_embedded

简单的使用:https://www.dengzhr.com/others/mobile/android/762

2.okhttp

3.retrofit

(1)支持 okhttp

(2)注解处理,简化代码

(3)支持上传和下载文件

(4)支持自己更换解析方式

(5)支持多种http请求库

二:图片加载框架

1.picasso :和square的网络库一起能发挥最大作用,因为picasso可以选择将网络请求的缓存部分交给了okhttp实现。

1.glide :模仿了picasso的api,而且在他的基础上加了很多的扩展(比如gif等支持),glide默认的bitmap格式是rgb_565,比

picasso默认的argb_8888格式的内存开销要小一半;picasso缓存的是全尺寸的(只缓存一种),而glide缓存的是跟

imageview尺寸相同的(即56*56和128*128是两个缓存) 。

3.总结:picasso所能实现的功能,glide都能做,无非是所需的设置不同。但是picasso体积比起glide小太多如果项目中网络请求本身用的

就是okhttp或者retrofit(本质还是okhttp),那么建议用picasso,体积会小很多(square全家桶的干活)。glide的好处是大型的图片流,

比如gif、video,如果你们是做美拍、爱拍这种视频类应用,建议使用。

三:activity

启动模式:

1.standard:默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相

同的实例,也允许多个相同activity叠加。

2.singletop:可以有多个实例,但是不允许多个相同activity叠加。即,如果activity在栈顶的时候,启动相同的activity,

不会创建新的实例,而会调用其onnewintent方法。

3.singletask:只有一个实例。在同一个应用程序中启动他的时候,若activity不存在,则会在当前task创建一个新的实例,

若存在,则会把task中在其之上的其它activity destory掉并调用它的onnewintent方法。

4.singleinstance:只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的activity存在。

生命周期:

1.oncreate:create表示创建,这个界面创建的时候就会执行此方法

2.onstart:启动这个界面,这个界面开始可见

3.onresume:这个界面可以交互,你可以点击,滑动等

4.onpause:这个界面可见,但是不可交互,

场景:activity 上面有一个对话框之类的,下面的界面可以见,但是无法交互

5.onstop:关闭这个界面,但是这个界面还是存在的,只是看不见

场景:按住home键,返回出去,但是这个活动还在,但是看不见了

6.ondestroy:将这个activity销毁,不可见,不可交互,可以做一些资源释放

7.onrestart:重新启动这个界面 执行 onstart onresume 不执行 oncreate方法

横竖屏切换:

1.不设置activity的android:configchanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2.设置activity的android:configchanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3.设置activity的android:configchanges="orientation|keyboardhidden"时,切屏不会重新调用各个生命周期,

只会执行onconfigurationchanged方法

android:screenorientation="portrait"

则无论手机如何变动,拥有这个属性的activity都将是竖屏显示。

android:screenorientation="landscape",为横屏显示

两个界面跳转:

打开app时

mainactivitya:oncreate —>在activitya对象被第一次创建时

mainactivitya:onstart —>activitya变得可见

mainactivitya:onresume —>开始准备与用户交互时调用

此时点击activitya中的按钮时:

mainactivitya:onpause —>即将启动另外一个activitb之前

otheractivityb:oncreate —>在activityb对象被第一次创建时

otheractivityb:onstart —>activityb变得可见

otheractivityb:onresume —>开始准备与用户交互时调用

mainactivitya:onstop —>当前activitya变得不可见时

点击activityb中的 返回 按钮时 :

otheractivityb:onpause —>即将启动另外一个activitb之前

mainactivitya:onrestart —>activitya再次启动之前

mainactivitya:onstart —>activitya变得可见

mainactivitya:onresume —>开始准备与用户交互时调用

otheractivityb:onstop —>当前activityb变得不可见时

otheractivityb:ondestroy —>当前activityb被销毁之前

mainactivitya:onstop —>当前activityb变得不可见时

mainactivitya:ondestroy —>当前activityb被销毁之前

四:handler机制、原理:

为什么要有handler:如果多线程并发的话就会造成界面混乱,不可控的状态。

handler , looper, massage,massagequeue

1.messagequeue:消息队列。虽然名为队列,但事实上它的内部存储结构并不是真正的队列,而是采用单链表

的数据结构来存储消息列表的,其中主要有插入enqueue()和从中拿走并删除next()两个方法。

2.looper:消息循环。messagequeue 来存储消息,looper 则是以无限循环的方式去查找是否有新消息,

如有就去处理,若没有就standby(等待).

注 : 一个线程创建handler时首先需要创建 looper 的,不然报错:但是ui线程是不需要创建的,

是因为 activitytread 创建时就初始化了 looper

3.handler:通过 sendmessage 或者 post 去将消息发送到messagequeue中,会调用 enqueuemessage() 方法,

而 messagequeue 的 next() 方法会将该消息返回给looper,looper接收到消息,就会处理

--looper 就交由 handler 的 dispatchmessage 方法

4.handler 的 dispatchmessage 方法最终会调用handlermessage 方法来处理消息:

五:自定义view:

1.自定义属性: values/新建一个 attrs.xml 文件

2.获取自定义属性:typedarray a = context.gettheme().obtainstyledattributes(attrs, r.styleable.customtitleview, defstyle, 0);

int n = a.getindexcount();

for (int i = 0; i < n; i++)

{

int attr = a.getindex(i);

switch (attr)

{

case r.styleable.customtitleview_titletext:

mtitletext = a.getstring(attr);

break;

case r.styleable.customtitleview_titletextcolor:

// 默认颜色设置为黑色

mtitletextcolor = a.getcolor(attr, color.black);

break;

case r.styleable.customtitleview_titletextsize:

// 默认设置为16sp,typevalue也可以把sp转化为px

mtitletextsize = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension(

typedvalue.complex_unit_sp, 16, getresources().getdisplaymetrics()));

break;

}

}

a.recycle();

3.重写 onmesure:

4、重写ondraw :

//画背景

mpaint.setcolor(color.yellow);

canvas.drawrect(0, 0, getmeasuredwidth(), getmeasuredheight(), mpaint);

//画自己设置的内容

mpaint.setcolor(mtitletextcolor);

canvas.drawtext(mtitletext, getwidth() / 2 - mbound.width() / 2, getheight() / 2 + mbound.height() / 2, mpaint);

六::https://www.cnblogs.com/picaso/archive/2012/05/17/2505895.html

七:fragment:android 3.0 引入

//创建了一个fragment 代表一个页面

public class test1fragment extends fragment {

//通过下面这个方法加载布局

@override

public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {

//加载布局 通过打气筒加载

return inflater.inflate(r.layout.fragment_test1, null);

}

}

1.获取 手机宽高:

//1.获取手机宽高

windowmanager wm = (windowmanager) getsystemservice(window_service);

int width = wm.getdefaultdisplay().getwidth();

int height = wm.getdefaultdisplay().getheight();

//2.获取一个fragment的管理者

fragmentmanager fragmentmanager = getfragmentmanager();

//2.1 开启fragment事务

fragmenttransaction fragmenttransaction = fragmentmanager.begintransaction();

//3.判断手机状态是横屏还是竖屏

if (height > width){

//说明是竖屏 加载一个页面 参数1:android.代表定义好的一些id 理解成是当前手机窗口

fragmenttransaction.replace(android.r.id.content,new test1fragment());

}else{

//说明是横屏 加载另外一个页面

fragmenttransaction.replace(android.r.id.content,new test2fragment());

}

//4.最后一步 记得提交事务

fragmenttransaction.commit();

八:listview与scrollview滑动冲突

4.最优方法,重写onmeasure方法 改变他回获取高度的方式

@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {

int expandspec = measurespec.makemeasurespec(integer.max_value >> 2,

measurespec.at_most);

super.onmeasure(widthmeasurespec, expandspec);

}

//其他方法:

1.在布局里面将listview的高度 固定,简单粗暴,适合新手

2.使用单个listview的addheaderview()方法添加一个头条目,检测状态,如果你需要检测头部状态的话,还是有冲突

3.使用linearlayout取代listview 用循环将数据添加进去。

九:listview的优化:

优化1:convertview的使用,主要优化加载布局问题

优化2:内部类viewholder的使用。减少findviewbyid()的次数;

优化3:static viewholder 类,只加载一次

额外优化:

1.有网络图片时:

如果你的listview中需要显示从网络上下载的图片的话,我们不要在listview滑动的时候加载图片,那样会使listview变得卡顿,

所以我们需要再监听器里面监听listview的状态,如果滑动的时候,停止加载图片,如果没有滑动,则开始加载图片

listview.setonscrolllistener(new onscrolllistener() {

@override

public void onscrollstatechanged(abslistview listview, int scrollstate) {

//停止加载图片

if (scrollstate == abslistview.onscrolllistener.scroll_state_fling) {

imageloader.stopprocessingqueue();

} else {

//开始加载图片

imageloader.startprocessingqueue();

}

}

@override

public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) {

// todo auto-ge nerated method stub

}

});

2 scrollingcache: scrollingcache本质上是drawing cache,你可以让一个view将他自己的drawing保存在cache中

(保存为一个bitmap),这样下次再显示view的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的,

因为它太耗内存了,但是它确实比重画来的更加平滑。而在listview中,scrollingcache是默认开启的,我们可以手动将它关闭。

3.animatecache: listview默认开启了animatecache,这会消耗大量的内存,因此会频繁调用gc,我们可以手动将它关闭掉

4.减少item的布局的深度;

十:a 应用启动 b 应用:

intent intent = getpackagemanager().getlaunchintentforpackage("com.xiecc.seeweather");

if (intent != null) {

intent.putextra("type", "110");

intent.setflags(intent.flag_activity_new_task);

startactivity(intent);

}

注:在次之前需要判断 b 应用是否存在

十一:网络七层协议

应用层 --> telnet,http,ftp,nfs,smtp 等。

表示层 --> ,ascii 等

会话层 --> rpc,sql 等。

传输层 --> tcp,udp,spx。这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,

网络层 --> ip,ipx 等。 它定义了在单个链路上如何传输数据

数据链路层 -->atm,fddi 等。

物理层 --> rj45,802.3等。

计算机组成:计算机组成指的是系统结构的逻辑实现,包括机器机内的数据流和控制流的组成及逻辑设计等。

主要分为五个部分:控制器,运算器,存储器,输入设备,输出设备。

十二:定位的坑

1.必须使用正式签名的apk。

2.必须使用真实手机测试,模拟机获取不到位置。

3.必须动态申请权限。(6.0以后)

error:execution failed for task ':app:transformclasseswithdexfordebug'.

> com.android.build.api.transform.transformexception: com.android.ide.common.process.processexception:

java.util.concurrent.executionexception: com.android.dex.dexexceptionle: multiple dex fis define landroid/support/v4/app/navutils$navutilsimpl;

注:以上错误是v4包重复,v7包 包含 v4包

十三:a 应用拉起 b 应用

1. 获取所有的包名

intent intent = new intent(intent.action_main, null);

intent.addcategory(intent.category_launcher);

apps = getpackagemanager().queryintentactivities(intent, 0);

2. 通过包名拉起响应的app

intent intent = mainactivity.this.getpackagemanager().getlaunchintentforpackage("com.xiecc.seeweather");

startactivity(intent);

十四:事件分发:

十五:支付宝支付流程

十六:wifi列表是空的: 必须打开 gps ;

十七:手机完全独立:im号,获取 ,存在问题 6.0, 无法获取,wifi地址 也被屏蔽,返回 0.0.0.0;手机当中有取出厂商编号,拼成字符串。

网络框架问得多。基础(okhttp,httpurlconnection) volley 与 retrofit 比较