码迷,mamicode.com
首页 > 移动开发 > 详细

android(二)

时间:2017-09-14 20:12:47      阅读:313      评论:0      收藏:0      [点我收藏+]

标签:当前时间   win   pil   dip   时间   ram   sdk开发   设置   actionbar   

Gradle中buildToolsVersion和TargetSdkVersion的区别是什么

compileSdkVersionminSdkVersion 和 targetSdkVersion 的作用:他们分别控制可以使用哪些 API ,要求的 API 级别是什么,以及应用的兼容模式。TargetSdkVersion 设为21那么是按6.0设置的(运行时权限),小于21是按6.0以前的方式


进程间怎么通信

binder是安卓中的一个类,它实现了IBinder接口,是安卓中跨进程通信的方式。当绑定服务的时候会返回一个binder对象,然后通过他进行多进程间的通信。

其实进程间通信就是为了实现数据共享。一个程序不同组件在不同进程也叫多进程,和俩个应用没有本质区别。使用process属性可以实现多进程,但是会带来很多麻烦,主要原因是共享数据会失败,弊端有:静态和单利失效,同步失效,sharedprefer可靠性减低等问题

Intent,Binder(AIDL),sharedpre、Messenger

  • 使用intent的附加信息extras来传递,通过bundle,传递的是bundle支持的类型,比如基本数据类型、实现pracellable或serializeable的对象
  • 使用文件共享,序列化或是sharedpre,不过不适用于读写并发的操作
  • 通过message进行传递,在远程服务里创建message对像,在onbind里返回(message.getbinder)。在客户端绑定服务,拿着message对象发消息(可以用bundle)。在远程服务的handlermessage方法就会收到。他是一个个处理的,如果大量并发请求用aidl,mrssage底层就是aidl
  • AIDL
  • socket可以实现俩个终端通信,也可以在一个设备的俩个进程通信。需要在服务里创建服务端
  • ContentProvider(进程间数据共享)和message一样,底层也是binder,除了oncreate方法其他方法(crud)都是运行在bindler线程里。所以在oncerate里不能做耗时操作。在其他应用访问通过uri(主机名),例如gercontentResolver.query(uri,null,null....)
  • 有以上6种

使用多进程显而易见的好处就是分担主进程的内存压力。我们的应用越做越大,内存越来越多,将一些独立的组件放到不同的进程,它就不占用主进程的内存空间了。当然还有其他好处,有心人会发现Android后台进程里有很多应用是多个进程的,因为它们要常驻后台,特别是即时通讯或者社交应用,不过现在多进程已经被用烂了。典型用法是在启动一个不可见的轻量级私有进程,在后台收发消息,或者做一些耗时的事情,或者开机启动这个进程,然后做监听等。还有就是防止主进程被杀守护进程,守护进程和主进程之间相互监视,有一方被杀就重新启动它。


AIDL的全称是什么?如何工作?

Android interface definition language (android接口定义语言) , 用来跨进程的访问方法。

应用场景:远程服务中的中间人对象,其他应用是拿不到的,那么在通过绑定服务获取中间人对象时,就无法强制转换,使用aidl,就可以在其他应用中拿到中间人类所实现的接口    


Aidl使用注意:

客服路径一致 接口名和文件名一致,远程服务的中间人Bind是继承XXX.Sub

Aidl文件中不要有权限修饰符,在客户端也是强转成XXX.Sub

onBind()3种返回:

1.继承Binder用它的对象返回,客户端将bind对象强转成自定义Bind

2.new一个Messenger时用Handler对象作为参数,用Messenger.getBinder()返回,客户端将bind对象强转成Messenger对象,在发送消息


支付宝远程服务

  1. 定义支付宝的服务,在服务中定义pay方法
  2. 定义中间人对象,把pay方法抽取成接口
  3. 把抽取出来的接口后缀名改成aidl
  4. 在自动生成的PublicBusiness.java文件中,有一个静态抽象类Stub,它已经继承了binder类,实现了publicBusiness接口,这个类就是新的中间人
  5. 中间人对象直接继承Stub对象,然后在onbind方法中把它返回出去
  6. 注册这个支付宝服务,定义它的intent-Filter,这样其他应用才可以访问。

需要支付的应用

  1. 把刚才定义好的aidl文件拷贝过来,注意aidl文件所在的包名必须跟原包名一致
  2. 远程绑定支付宝的服务,通过onServiceConnected方法我们可以拿到中间人对象
  3. 把中间人对象通过Stub.asInterface方法强转成定义了pay方法的接口
  4. 调用中间人的pay方法


对称加密和非对称加密

对称加密,就是加密和解密数据都是使用同一个key,这方面的算法有DES。 非对称加密,加密和解密是使用不同的key。发送数据之前要先和服务端约定生成公钥和私钥,使用公钥加密的数据可以用私钥解密,反之。这方面的算法有RSA。ssh 和 ssl都是典型的非对称加密。



假设手机本地需要缓存数据,如何保证和服务器的数据统一?

  • 比如有个网络更新的功能,activity可以每隔半小时开启service去访问服务器,获取最新的数据。

  • 在缓存文件里面加入时间戳,根据实际情况在一定的时间差内再次访问网络数据、判断URL

在缓存的第一行写一个上当前时间,读的时候判断是不是过期,根据需求看需要多久跟新


分页怎么做的?

分页根据服务器接口参数决定每次加载多少,getviewtype,getitemview

分批处理 解决的是时间等待的问题,不能解决内存占用的问题。

要想解决内存占用问题,可以采用分页方式


Listview如何显示不同条目?

第一种:在getview方法里根据position 进行判断,比如,position等于0是,显示标题,否则显示数据,当然相应的setOnItemClickListener也要去判断

第二种:根据listview里的getItemViewType,getViewTypeCount方法显示不同条目

	/** 根据位置 判断当前条目是什么类型 */
	@Override
	public int getItemViewType(int position) {  //20     
		if (position == datas.size()) { // 当前是最后一个条目
			return MORE_ITEM;
		}
		return getInnerItemViewType(position); // 如果不是最后一个条目 返回默认类型
	}
	private int getInnerItemViewType(int position) {
		return DEFAULT_ITEM;
	}
	/** 当前ListView 有几种不同的条目类型 */
	@Override
	public int getViewTypeCount() {
		return super.getViewTypeCount() + 1; // 2 有两种不同的类型
	}


TextView ImageView Button,ImageButton他们之间的联系和区别

TextView 控件继承自 View 类。TextView控件的功能是向用户显示文本内容,TextView不允许编辑。

EditText控件继承自 TextView。EditText与TextView 最大的不同是 EditText是可以编辑的

ImageView 控件负责显示图片,其图片来源既可以是资源文件的id,也可以是Drawable对象或 Bitmap 对象,还可以是 内容提供者(Content Provider)的Uri.

Button控件继承自 TextView 类,Button 的用法比较简单,主要是为 Button 设置一个点击事件监听器,并在编写按钮点击事件的处理代码。

ImageButton 控件 继承自 ImageView。与Button相同之处:都用于响应按钮的点击事件

不同之处:ImageButton只能显示图片;Button用于显示文字


屏幕适配

  • 开发时选取主流屏幕 1280*120 用相对布局和线性布局 还有权重
  • 用dp sp不用px 开发后期在不同的分辨率上测试,没有太大问题可以上线
  • 图片适配:切几套图 apk太大
  • 布局适配:layout-800x180 针对某一种屏幕 工作量大
  • 尺寸适配:dp=px/设备密度=getResource().getDisplayMetrice().dsnsity;


 根据不同分辨率的屏幕建立不同的,比如valuse-1280x720,values里的dimens里算出dp,最后引用系统会自动匹配。

 (约等于)320*240(0.5) 480*320(1) 480*800(1.5) 1280*720(2)就不用布局适配了

Density-independent pixel (dp)独立像素密度。标准是160dip.即1dp对应1个pixel,计算公式如:px = dp * (dpi / 160),屏幕密度越大,1dp对应 的像素点越多。 
上面的公式中有个dpi,dpi为DPI是Dots Per Inch(每英寸所打印的点数),也就是当设备的dpi为160的时候1px=1dp;

mdpi、hdpi、xdpi、xxdpi

其实之前还有个ldpi,但是随着移动设备配置的不断升级,这个像素密度的设备已经很罕见了,所在现在适配时不需考虑。

mdpi、hdpi、xdpi、xxdpi用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。

那么如何区分呢?Google官方指定按照下列标准进行区分:

技术分享

在进行开发的时候,我们需要把合适大小的图片放在合适的文件夹里面。下面以图标设计为例进行介绍。

技术分享

在设计图标时,对于五种主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)应按照 2:3:4:6:8 的比例进行缩放。例如,一个启动图标的尺寸为48x48 dp,这表示在 MDPI 的屏幕上其实际尺寸应为 48x48 px,在 HDPI 的屏幕上其实际大小是 MDPI 的 1.5 倍 (72x72 px),在 XDPI 的屏幕上其实际大小是 MDPI 的 2 倍 (96x96 px),依此类推。

来源: http://www.cocoachina.com/android/20151030/13971.html



  • 权重适配:weight 只有线性布局有
  • 代码适配:getWindowManager().getDefaultDisplay().getWidth();获得屏幕的宽高
  • 指定宽高的时候,采用 dip 的单位,dp单位动态匹配
  • 尽量使用线性布局,相对布局,如果屏幕放不下了,可以使用 ScrollView(可以上下拖动)

请介绍下Android中常用的五种布局。

FrameLayout(帧布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)

  • FrameLayout:从屏幕的左上角开始布局,叠加显示, 实际应用 播放器的暂停按钮.
  • LinearLayout:线性布局,他首先是一个一个从上往下罗列在屏幕上。每一个LinearLayout里面又可分为垂直布局、水平布局。当垂直布局时,每一行就只有一个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次向右排列。
  • AbsoluteLayout:用X,Y坐标来指定元素的位置android:layout_x="20px" ,android:layout_y="12px" ,指定平板机型的游戏开发、机顶盒开发中经常用到绝对布局
  • RelativeLayout:在相对的布局中主要就进行避免覆盖的问题,就是组件1可能会覆盖在组件2上(屏幕适配),在相对的布局中主要就进行避免覆盖的问题,就是组件1可能会覆盖在组件2上
  • TableLayout:有几行,就有几个<TableRow/>,有几列,那么在<TableRow>中就有几个<TestView>,TableRow的子节点的宽和高是包裹内容,不需要指定宽高


RelativeLayout和FrameLayout的区别

FrameLayout主要是在多层之间的布局,RelativeLayout则是在同层之间不同位置之间的布局,效果上没有什么大的区别,都可以实现,只是看哪种实现更容易。比如我们收到信息了,我们可以在信息图标上增加FrameLayout 用于显示气泡。


Padding和Margin有什么区别?

Padding 是控件内容的距离margin是控件和控件间的距离


技术分享


对android主线程的运用和理解

主ui线程不能执行耗时的操作

技术分享




什么Context

Android工程环境中像Activity、Service、BroadcastReceiver等系统组件,而这些组件并不是像一个普通的Java对象new一下就能创建实例的了,而是要有它们各自的上下文环境,这就是Context。可以这样讲,Context是维持Android程序中各组件能够正常工作的一个核心功能类。

Context功能很多,可以弹出Toast、启动Activity、启动Service、发送广播、操作数据库等等等等都需要用到Context。

Context一共有Application、Activity和Service三种类型:Context数量 = Activity数量 + Service数量 + 1 。1代表着Application的数量,因为一个应用程序中可以有多个Activity和多个Service,但是只能有一个Application。
Application通常作为工具类来使用的,Application中在onCreate()方法里去初始化各种全局的变量数据是一种比较推荐的做法,但是如果你想把初始化的时间点提前到极致,也可以去重写attachBaseContext()方法。不能写在构造函数里。

Android程序与Java程序的区别?

Android程序用android sdk开发,java程序用javasdk开发.

Android SDK引用了大部分的Java SDK,少数部分被Android SDK抛弃,比如说界面部分,java.awt swing package除了java.awt.font被引用外,其他都被抛弃,在Android平台开发中不能使用。 android sdk 添加工具jar httpclient , pull opengl



dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念

Dvm的进程是dalivk虚拟机进程,每个android程序都运行在自己的进程里面,

每个android程序系统都会给他分配一个单独的liunx uid(user id),

每个dvm都是linux里面的一个进程.所以说这两个进程是一个进程.



ScrowView 使用的注意

在不同的屏幕上显示内容不同的情况,其实这个问题我们往往是用滚动视图来解决的,也就是 ScrowView;需要

    注意的是 ScrowView 中使用 layout_weight 是无效的,既然使用 ScrowView 了,就把它里面的控件的大小都设成固定的吧。


    Android UI中的View如何刷新。

    在主线程中  拿到view调用Invalide()方法,在子线程里面可以通过postInvalide()方法;

    invalidate();//主线程,刷新当前视图  导致 执行onDraw执行

    postInvalidate();//子线程


    什么是ANR(异步加载) 如何避免它?

    android在主线程是不能加载网络数据或图片、数据库查询、复杂业务逻辑处理以及费时任务操作,因为AndroidUI操作并不是线程安全的,并且所有涉及UI的操作必须在UI线程中完成。Android应用在5s内无响应的话会导致ANR(Application Not Response),这就要求开发者必须遵循两条法则:1、不能阻塞UI线程,2、确保只在UI线程中访问Android UI工具包。

    Activity 5秒  broadcast10秒,服务20秒,耗时的操作在主thread里面完成

    解决办法:Thread + Handler + Message ,Thread + Handler + post,AsyncTask,intentservice

    runOnUiThread(Runnable)在子线程中直接使用该方法,可以更新UI


    Android中的动画有哪几类,它们的特点和区别是什么?

    两种,一种是补间动画、还有一种是帧动画。

    补间动画是放置到res/anim/下面

    帧动画是放置到res/drawable/下面

    补间动画

    • 如果动画中的图像变换比较有规律时,可以才用自动生成中间图像的方式生成动画,例如图像的移动、旋转、缩放、透明度渐变、正方形变圆形等,这些图像变化过程中的图像都可以根据一定的算法自动生成,我们只需要指定动画的第一帧和最后一帧图像即可,这种自动生成中间图像的动画就是补间动画。
    • 原形态变成新形态时为了过渡变形过程,生成的动画就叫补间动画
    • 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变
    • 位移、旋转、缩放、透明

    帧动画:传统的动画方法,通过顺序的播放排列好的图片来实现,类似电影,一张张图片不断的切换,形成动画效果,要自己指定每一帧

    在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长

    属性动画:动画的对象除了传统的View对象,还可以是Object对象,动画结束后,Object对象的属性值被实实在在的改变了


    实现侧边栏、和指示器效果、页面滑动有几种方式

    侧边栏:自定义、slidingmenu、DrawerLayout 、SlidingDrawer

    指示器效果:自定义、viewpager里面的PagerTabStrip、ActionBar Tab标签、viewpagerindicate、FragmentTabHost、TabActivity、radiobutton

    页面滑动:自定义、viewpager、手势识别器,其实就是onTouchEvent提供的简单工具类,onTouchEvent将触摸事件委托给了手势识别器


    Android工程的目录结构 

    src:项目的java代码

    assets:资源文件夹,存放视频或者音乐等较大的资源文件

    bin:存放应用打包编译后的文件

    res:资源文件夹,在这个文件夹中的所有资源,都会有资源id,读取时通过资源id就可以读取

         资源id不能出现中文



    如何缩减APK包大小

    代码

    保持良好的编程习惯,不要重复或者不用的代码,谨慎添加libs,移除使用不到的libs。
    使用proguard混淆代码,它会对不用的代码做优化,并且混淆后也能够减少安装包的大小。
    native code的部分,大多数情况下只需要支持armabi与x86的架构即可。如果非必须,可以考虑拿掉x86的部分。

    资源

    使用Lint工具查找没有使用到的资源。去除不使用的图片,String,XML等等。
    assets目录下的资源请确保没有用不上的文件。
    生成APK的时候,aapt工具本身会对png做优化,但是在此之前还可以使用其他工具如tinypng对图片进行进一步的压缩预处理。
    jpeg还是png,根据需要做选择,在某些时候jpeg可以减少图片的体积。
    对于9.png的图片,可拉伸区域尽量切小,另外可以通过使用9.png拉伸达到大图效果的时候尽量不要使用整张大图。

    策略

    有选择性的提供hdpi,xhdpi,xxhdpi的图片资源。建议优先提供xhdpi的图片,对于mdpi,ldpi与xxxhdpi根据需要提供有差异的部分即可。
    尽可能的重用已有的图片资源。例如对称的图片,只需要提供一张,另外一张图片可以通过代码旋转的方式实现。
    能用代码绘制实现的功能,尽量不要使用大量的图片。例如减少使用多张图片组成animate-list的AnimationDrawable,这种方式提供了多张图片很占空间。


    多线程断点下载

    单线程的话从输入流的第0个字节读取

    原理:服务器CPU分配给每条线程的时间片相同,服务器带宽平均分配给每条线程,所以客户端开启的线程越多,就能抢占到更多的服务器资源。所以要用多线程去读取。

    请求网络时首先获取资源长度设置被进度条,然后除以要开启的线程数,计算出每个线程应该下载多少字节。然后每个线程去请求网络读取数据。

        //设置本次http请求所请求的数据的区间
                    conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
                    
                    //请求部分数据,相应码是206
                    if(conn.getResponseCode() == 206){
                        //流里此时只有1/3原文件的数据
                        InputStream is = conn.getInputStream();
    int length = conn.getContentLength();
        //设置本次http请求所请求的数据的区间
                    conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
                    
                    //请求部分数据,相应码是206
                    if(conn.getResponseCode() == 206){
                        //流里此时只有1/3原文件的数据
                        InputStream is = conn.getInputStream();

    特别注意: 对于移动端来说,如果不是比较大的文件,不建议使用这种方式上传,因为断点续传是通过分片上传实现的,上传单个文件需要进行多次网络请求,效率不高。


    coverview原理:

    这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用,在 getView()方法中进行了判断,如果 convertView为空,则使用

    LayoutInflater去加载布局,如果不为空则直接对 convertView进行重用


    layout_weight(为t),屏幕适配经常用

    等分的长度“先各自分配各自控件的长度,然后将剩余的长度按照权重的比例layout_weight的大小进行设置。

    如果父类的组件的设置为vertical,那么layout_height=0(layout_weight=1)

    如果父类的组件的设置为horionzal,那么layout_width=0(layout_weight=1)


    android的启动流程

    当程序启动Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init.c),加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,然后接着在里面启动各种硬件服务和activity。Android系统启动完成,打开了Luncher应用的Home界面。


    Logcat

    1. Log.v()

    这个方法用于打印那些最为琐碎的,意义最小的日志信息。对应级别 verbose,是Android日志里面级别最低的一种。

    2. Log.d()

    这个方法用于打印一些调试信息, 这些信息对你调试程序和分析问题应该是有帮助的。对应级别 debug,比 verbose高一级。

    3. Log.i()

    这个方法用于打印一些比较重要的数据,这些数据应该是你非常想看到的,可以帮你分析用户行为的那种。对应级别 info,比 debug高一级。

    4. Log.w()

    这个方法用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别 warn,比 info高一级。

    5. Log.e()

    这个方法用于打印程序中的错误信息,比如程序进入到了 catch语句当中。当有错误信息打印出来的时候,一般都代表你的程序出现严重问题了,必须尽快修复。对应级别 error,比 warn高一级.


    推送

    所有需要客户端被动接收信息的功能模块,都可以用推送实现,比如A想给B发消息,A调服务器接口,服务器只是存数据,它调推送的接口,推送去去找B。推送用的是xmpp协议, 是一种基于TCP/IP的协议, 这种协议更适合消息发送

    - socket 套接字, 发送和接收网络请求
    - 长连接 keep-alive, 服务器基于长连接找到设备,发送消息
    - 心跳包 , 客户端会定时(30秒一次)向服务器发送一段极短的数据,作为心跳包, 服务器定时收到心跳,证明客户端或者,才会发消息.否则将消息保存起来,等客户端活了之后(重新连接),重新发送.


    系统架构:

    技术分享

    系统分层: (由下向上) 【如图】

    1、安卓系统分为四层,分别是 Linux 内核层、Libraries 层、FrameWork层,以及 Applications 层:

    • Linux 内核层:包含 Linux 内核和驱动模块(比如 USB、Camera、蓝牙等)
    • Libraries 层:这一层提供动态库(也叫共享库) 、android 运行时库、Dalvik 虚拟机等。编程语言主要为 C 或 C++,所以可以简单的看成 Native 层。
    • FrameWork层:这一层大部分用 java 语言编写,它是 android 平台上 Java 世界的基石。
    • Applications 层:应用层

    FrameWork层 -------- Java 世界

    Libraries 层 -------- Native 世界

    Linux 内核层 -------- Linux OS

    Java 世界和 Native 世界间的通信是通过 JNI 层,JNI 层和 Native 世界都可以直接调用系统底层

    2、Dalvik VM 和传统 JVM 的区别:

    传统的 JVM:编写.java 文件→编译为.class 文件 → 打包成.jar 文件

    Dalvik VM: 编写.java 文件 → 编译为.class 文件 → 打包成.dex文件 → 打包成.apk文件(通过 dx工具)

    将所有的类整合到一个文件中,提高了效率。更适合在手机上运行



    Android逆向工程是什么?

    Android逆向工程主要是指反编译和二次打包,通过反编译可以破解一些有用信息,而通过二次打包则可以产生一些山寨应用。Android逆向工程是一个很有意思的话题,如果开发者对其感兴趣的话,推荐大家阅读下逆向相关的书籍,比如《Android软件安全与逆向分析》。








    android(二)

    标签:当前时间   win   pil   dip   时间   ram   sdk开发   设置   actionbar   

    原文地址:http://www.cnblogs.com/liuyu0529/p/7522081.html

    (0)
    (0)
       
    举报
    评论 一句话评论(0
    登录后才能评论!
    © 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
    迷上了代码!