android一般题目

android开发中可能会出现的一些常见的问题:

http请求:

一般请求分为GET请求和POST请求,区别如下:

  • GET请求可以被缓存。
  • 我们之前提到,当发送键值对信息时,可以在URL上面直接追加键值对参数。当用GET请求发送键值对时,键值对会随着URL一起发送的。
  • 由于GET请求发送的键值对时随着URL一起发送的,所以一旦该URL被黑客截获,那么就能看到发送的键值对信息,所以GET请求的安全性很低,不能用GET请求发送敏感的信息(比如用户名密码)。
  • 由于URL不能超过2048个字符,所以GET请求发送数据是有长度限制的。
  • 由于GET请求较低的安全性,我们不应该用GET请求去执行增加、删除、修改等的操作,应该只用它获取数据。
  • POST请求从不会被缓存。
  • POST请求的URL中追加键值对参数,不过这些键值对参数不是随着URL发送的,而是被放入到请求体中发送的,这样安全性稍微好一些。
  • 应该用POST请求发送敏感信息,而不是用GET。
  • 由于可以在请求体中发送任意的数据,所以理论上POST请求不存在发送数据大小的限制。
  • 当执行增减、删除、修改等操作时,应该使用POST请求,而不应该使用GET请求。
下面介绍目前请求使用请求常见的两个类:

HttpURLConnection vs DefaultHttpClient

在Android API Level 9(Android 2.2)之前之能使用DefaultHttpClient类发送http请求。DefaultHttpClient是Apache用于发送http请求的客户端,其提供了强大的API支持,而且基本没有什么bug,但是由于其太过复杂,Android团队在保持向后兼容的情况下,很难对DefaultHttpClient进行增强。为此,Android团队从Android API Level 9开始自己实现了一个发送http请求的客户端类——–HttpURLConnection。

相比于DefaultHttpClient,HttpURLConnection比较轻量级,虽然功能没有DefaultHttpClient那么强大,但是能够满足大部分的需求,所以Android推荐使用HttpURLConnection代替DefaultHttpClient,并不强制使用HttpURLConnection。

但从Android API Level 23(Android 6.0)开始,不能再在Android中使用DefaultHttpClient,强制使用HttpURLConnection。

请求的参数可以使用Map或者List<NameValuePair>等来封装上传的数据。

一些常见的状态码为:

  200 - 服务器成功返回网页

  404 - 请求的网页不存在

  503 - 服务器超时

HTTP状态码一览表。

1xx:请求收到,继续处理
2xx:操作成功收到,分析、接受
3xx:完成此请求必须进一步处理
4xx:请求包含一个错误语法或不能完成
5xx:服务器执行一个完全有效请求失败


数据解析:

目前移动端一般使用json来解析,一般用JSONObjectJSONArray来解析数据,解释见下:

public class 
JSONObject
extends Object

org.json.JSONObject

Class Overview
A modifiable set of name/value mappings. Names are unique, non-null strings. Values may be any mix of JSONObjects, JSONArrays, Strings, Booleans, Integers, Longs, Doubles or NULL. Values may not be null, NaNs, infinities, or of any type not listed here. 

JSONObject(String json) 
Creates a new JSONObject with name/value mappings from the JSON string.
 
Object  get(String name) 
Returns the value mapped by name. 

int  getInt(String name) 
Returns the value mapped by name if it exists and is an int or can be coerced to an int. 

String  getString(String name) 
Returns the value mapped by name if it exists, coercing it if necessary. 

JSONArray  getJSONArray(String name) 
Returns the value mapped by name if it exists and is a JSONArray. 

public class 
JSONArray
extends Object

org.json.JSONArray

Class Overview
A dense indexed sequence of values. Values may be any mix of JSONObjects, other JSONArrays, Strings, Booleans, Integers, Longs, Doubles, null or NULL. Values may not be NaNs, infinities, or of any type not listed here. 

JSONObject  getJSONObject(int index) 

Returns the value at index if it exists and is a JSONObject.


JSONStringer   :用来生成json ,实际上就是JSONArray和JSONObject配合使用。

Stringers only encode well-formed JSON strings. In particular:

  • The stringer must have exactly one top-level array or object.
  • Lexical scopes must be balanced: every call to array() must have a matching call to endArray() and every call to object() must have a matching call to endObject().  //每次调用array(),必须匹配endArray,object,endObject同理。
  • Arrays may not contain keys (property names).
  • Objects must alternate keys (property names) and values.
  • Values are inserted with either literal value calls, or by nesting arrays or objects.


JSON Vs XML

1.JSON和XML的数据可读性基本相同

2.JSON和XML同样拥有丰富的解析手段

3.JSON相对于XML来讲,数据的体积小

4.JSON与JavaScript的交互更加方便

5.JSON对数据的描述性比XML较差

6.JSON的速度要远远快于XML


图片压缩:

一般使用BitmapFactory进行图片的读入,压缩,展示。

1、等比压缩,等比压缩是保持原图长宽比例的压缩,只是图片变小,展示的还是原图的所有内容(区别于第二种通过Matrix压缩,可以选取图片的一部分,类似于上传头像时,让你在图上选一块zoom的形式)。等比压缩用的的主要是BitmapFactory.Options,通过options缩放比例的设置,来生成缩略图。

一般化的压缩代码见下:

    /** 
     * 图片按比例大小压缩方法 
     * 
     * @param srcPath (根据路径获取图片并压缩) 
     * @return 
     */  
    public static Bitmap getimage(String srcPath) {  
      
        BitmapFactory.Options newOpts = new BitmapFactory.Options();  
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
        newOpts.inJustDecodeBounds = true;  
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空  
      
        newOpts.inJustDecodeBounds = false;  
        int w = newOpts.outWidth;  
        int h = newOpts.outHeight;  
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
        float hh = 800f;// 这里设置高度为800f  
        float ww = 480f;// 这里设置宽度为480f  
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
        int be = 1;// be=1表示不缩放  
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
            be = (int) (newOpts.outWidth / ww);  
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放  
            be = (int) (newOpts.outHeight / hh);  
        }  
        if (be <= 0)  
            be = 1;  
        newOpts.inSampleSize = be;// 设置缩放比例  
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩  
    }  

    /** 
     * 质量压缩方法 
     * 
     * @param image 
     * @return 
     */  
    public static Bitmap compressImage(Bitmap image) {  
      
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中  
        int options = 90;  
      
        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩  
            baos.reset(); // 重置baos即清空baos  
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中  
            options -= 10;// 每次都减少10  
        }  
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中  
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片  
        return bitmap;  
    }  


2、通过Matrix进行更加灵活的缩放:这种方式主要是通过构建缩放矩阵和Bitmap.createBitmap方法来实现灵活缩放,宽和高缩放的比例可以不一致,而且通过Bitmap.createBitmap方法创建出来的是新的位图,这个位图可以是选取原图的一部分,而不是对原图进行整体缩放!类似于上传头像时,让你在原图上扣下来一块的效果,控制非常灵活。

图片格式:

一般格式主要有jpg,png,

二者对比:
1、png有透明通道,而jpg没有
2、png是无损压缩的,而jpg是有损压缩,因此png中存储的信息会很多,体积自然就大了
3、手机对png情有独钟,会对其进行硬件加速,所以同样一张背景图,png虽然体积大,但是加载速度更快

综述:1、对于app包中的图片,我们都使用png格式的,而对于要从网络上加载的图片,考虑到流量以及下载上速度,则使用jpg格式的,因为它有较高的压缩率,体积更小。
2、对于背景图、引导页,这种大尺寸的图片,我们还是倾向于jpg格式的,虽然加载慢一些吗,但是体积小,减少了包的体积
3、Google后来发布了一种新的图片格式,WebP,它的压缩率比jpg更好,已经在慢慢普及

其实图片内部编码等比较复杂,简单说下:

1、ImageFormat(android.graphics.ImageFormat),格式参数有以下几种:

    /**
     * Use this function to retrieve the number of bits per pixel of an
     * ImageFormat.
     *
     * @param format
     * @return the number of bits per pixel of the given format or -1 if the
     *         format doesn't exist or is not supported.
     */
    public static int getBitsPerPixel(int format) {
        switch (format) {
            case RGB_565:
                return 16;
            case NV16:
                return 16;
            case YUY2:
                return 16;
            case YV12:
                return 12;
            case Y8:
                return 8;
            case Y16:
                return 16;
            case NV21:
                return 12;
            case YUV_420_888:
                return 12;
            case RAW_SENSOR:
                return 16;
            case BAYER_RGGB:
                return 16;
        }
        return -1;
    }
解释:

int JPEG ,Encoded formats,常量值: 256 (0x00000100)

int NV16,YCbCr format, used for video,16 (0x00000010)

int NV21,YCrCb format used for images, which uses the NV21 encoding format,常量值: 17 (0x00000011)

int RGB_565,RGB format used for pictures encoded as RGB_565,常量值: 4 (0x00000004)

int UNKNOWN, 常量值:0 (0x00000000)

int YUY2,YCbCr format used for images,which uses YUYV (YUY2) encoding format,20 (0x00000014)

int YV12,Android YUV format,This format is exposed to software decoders and applications

YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed by (W/2) x (H/2) Cr and Cb planes 

上面是说图片的格式,这里说说像素格式:

2、PixelFormat(android.graphics.PixelFormat),格式参数有以下几种:

int A_8,常量值:8 (0x00000008)

int JPEG,常量值:256 (0x00000100),constant,已声明不赞成使用,use ImageFormat.JPEG instead.

int LA_88,常量值:10 (0x0000000a)

int L_8, 常量值:9 (0x00000009)

int OPAQUE,常量值: -1 (0xffffffff),System chooses an opaque format (no alpha bits required)

int RGBA_4444,常量值:7 (0x00000007)

int RGBA_5551,常量值:6 (0x00000006)

int RGBA_8888,常量值:1 (0x00000001)

int RGBX_8888,常量值:2 (0x00000002)

int RGB_332,常量值:11 (0x0000000b)

int RGB_565,常量值:4 (0x00000004)

int RGB_888,常量值:3 (0x00000003)

int TRANSLUCENT,常量值: -3 (0xfffffffd),System chooses a format that supports translucency (many alpha bits)

int TRANSPARENT,常量值:-2 (0xfffffffe),System chooses a format that supports transparency (at least 1 alpha bit)

int UNKNOWN,常量值: 0 (0x00000000)

int YCbCr_420_SP,常量值:17 (0x00000011),constant 已声明不赞成使用 use ImageFormat.NV21 instead

int YCbCr_422_I,常量值: 20 (0x00000014),constant 已声明不赞成使用 use ImageFormat.YUY2 instead

int YCbCr_422_SP,常量值:16 (0x00000010),constant 已声明不赞成使用 use ImageFormat.NV16 instead

注意,有四种图像格式已被声明不赞成使用,可以用ImaggFormat相对应的格式进行代替。由此可知,两种图像格式之间存在相通之处。用法举例,让窗口实现渐变的效果,如

1 getWindow().setFormat(PixelFormat.RGBA_8888);
补充说明:RGBA_8888为android的一种32位颜色格式,R、G、B、A分别用八位表示,Android默认的图像格式是PixelFormat.OPAQUE,其是不带Alpha值的

3、Bitmap.Config(Android.graphics.Bitmap内部类)

Possible bitmap configurations。A bitmap configuration describes how pixels are stored。This affects the quality (color depth) as well as the ability to display transparent/translucent colors。(官网介绍,大致意思是说:影响一个图片色彩色度显示质量主要看位图配置,显示图片时透明还是半透明)。

ALPHA_8:Each pixel is stored as a single translucency (alpha) channel。(原图的每一个像素以半透明显示)

ARGB_4444:This field was deprecated in API level 13。Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead。(在API13以后就被弃用了,建议使用8888)。

ARGB_8888 :Each pixel is stored on 4 bytes。 Each channel (RGB and alpha for translucency) is stored with 8 bits of precision (256 possible values) 。This configuration is very flexible and offers the best quality。 It should be used whenever possible。(每个像素占4个字节,每个颜色8位元,反正很清晰,看着很舒服)。

RGB_565:Each pixel is stored on 2 bytes and only the RGB channels are encoded:red is stored with 5 bits of precision (32 possible values),green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision。(这个应该很容易理解了)。

用法举例,构建Bitmap对象时,会用到BitmapConfig类图像格式对象,如:

1 Bitmap bitmap = Bitmap.createBitmap(width, height,Bitmap.Config.RGB_565)
图片格式之间的相互转换略,可以参考文章http://www.open-open.com/lib/view/open1438051625316.html,本段摘自该处。

适配:

图片的适配一般是切几套图,分别放在hdpi,xhdip,xxhdpi等文件夹中,系统会自动选择合适的图片去加载,布局的适配一般是建立values-hdpi,values-xhdpi,values-xxhdpi文件夹来适配,文件夹下有dimens.xml文件,里面会对需要修改偏移距离等地方增加相应的值,同一个key在不同的dimens文件中的值不同,便会适配各种屏幕。

适配方面多用相对布局,不要写死大小,偏移距离等单位多用dp,字体多用sp,就会好适配些。

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

SP:与缩放无关的抽象像素(Scale-independent Pixel)。sp和dp很类似但唯一的区别是,Android系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是“正常”时1sp=1dp=0.00625英寸,而当文字尺寸是“大”或“超大”时,1sp>1dp=0.00625英寸。类似我们在windows里调整字体尺寸以后的效果——窗口大小不变,只有文字大小改变。


事件分发:


从上图中我们可以看到 ViewGroup 及其子类对与 Touch 事件相关的三个方法均能响应,而 Activity 对onInterceptTouchEvent(MotionEvent ev) 也就是事件拦截不进行响应。另外需要注意的是 View 对dispatchTouchEvent(MotionEvent ev)onInterceptTouchEvent(MotionEvent ev) 的响应的前提是可以向该 View 中添加子 View,如果当前的 View 已经是一个最小的单元 View(比如 TextView),那么就无法向这个最小 View 中添加子 View,也就无法向子 View 进行事件的分发和拦截,所以它没有dispatchTouchEvent(MotionEvent ev)onInterceptTouchEvent(MotionEvent ev),只有onTouchEvent(MotionEvent ev)

事件分发:public boolean dispatchTouchEvent(MotionEvent ev)

Touch 事件发生时Activity 的 dispatchTouchEvent(MotionEvent ev) 方法会以隧道方式(从根元素依次往下传递直到最内层子元素或在中间某一元素中由于某一条件停止传递)将事件传递给最外层 View 的 dispatchTouchEvent(MotionEvent ev) 方法,并由该 View 的 dispatchTouchEvent(MotionEvent ev) 方法对事件进行分发。dispatchTouchEvent 的事件分发逻辑如下:

  • 如果return true,事件会分发给当前 View 并由 dispatchTouchEvent 方法进行消费,同时事件会停止向下传递;
  • 如果return false,事件分发分为两种情况:
  1. 如果当前 View 获取的事件直接来自 Activity,则会将事件返回给 Activity 的 onTouchEvent 进行消费;
  2. 如果当前 View 获取的事件来自外层父控件,则会将事件返回给父 View 的  onTouchEvent 进行消费。
  • 如果返回系统默认的super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。

事件拦截:public boolean onInterceptTouchEvent(MotionEvent ev)

外层 View 的 dispatchTouchEvent(MotionEvent ev) 方法返回系统默认的 super.dispatchTouchEvent(ev) 情况下,事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。onInterceptTouchEvent的事件拦截逻辑如下:

  • 如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
  • 如果 onInterceptTouchEvent 返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发;
  • 如果 onInterceptTouchEvent 返回 super.onInterceptTouchEvent(ev),事件默认会被拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理。

事件响应:public boolean onTouchEvent(MotionEvent ev)

在 dispatchTouchEvent 返回 super.dispatchTouchEvent(ev) 并且 onInterceptTouchEvent 返回 true 或返回 super.onInterceptTouchEvent(ev) 的情况下 onTouchEvent 会被调用。onTouchEvent的事件响应逻辑如下:

  • 如果事件传递到当前 View 的 onTouchEvent 方法,而该方法返回了 false,那么这个事件会从当前 View 向上传递,并且都是由上层 View 的 onTouchEvent 来接收,如果传递到上面的 onTouchEvent 也返回 false,这个事件就会“消失”,而且接收不到下一次事件。
  • 如果返回了 true 则会接收并消费该事件。
  • 如果返回 super.onTouchEvent(ev) 默认处理事件的逻辑和返回 false 时相同。

到这里,与 Touch 事件相关的三个方法就分析完毕了。下面的内容会通过各种不同的的测试案例来验证上文中三个方法对事件的处理逻辑。

总结:

1、如果ViewGroup找到了能够处理该事件的View,则直接交给子View处理,自己的onTouchEvent不会被触发;

2、可以通过复写onInterceptTouchEvent(ev)方法,拦截子View的事件(即return true),把事件交给自己处理,则会执行自己对应的onTouchEvent方法

3、子View可以通过调用getParent().requestDisallowInterceptTouchEvent(true);  阻止ViewGroup对其MOVE或者UP事件进行拦截;


好了,那么实际应用中能解决哪些问题呢?

比如你需要写一个类似slidingmenu的左侧隐藏menu,主Activity上有个Button、ListView或者任何可以响应点击的View,你在当前View上死命的滑动,菜单栏也出不来;因为MOVE事件被子View处理了~ 你需要这么做:在ViewGroup的dispatchTouchEvent中判断用户是不是想显示菜单,如果是,则在onInterceptTouchEvent(ev)拦截子View的事件;自己进行处理,这样自己的onTouchEvent就可以顺利展现出菜单栏了~~

屏幕事件处理,手势识别:

平时使用较少,此处简略写一下:

android中提供了MotionEvent,GestureDetector等来方便识别各种手势操作。

MotionEvent: Object used to report movement (mouse, pen, finger, trackball) events.
  Motion events may hold either absolute or relative movements and other data,  depending on the type of device.

getAction()方法返回的是int类型,用到的只有低16位,其中:低八位是动作的类型,高8位是触摸点索引值的表示(单点为0,双点为1)

UI展示:

ui展示基本使用到的是view和widget等组合方式来显示各种各样的文字,图片,选框等内容,组合成一个操作窗口。

view包下主要有view,surfaceview,windowmanager等一些操作显示类,widget包下都是google封装的一些ui组件,比如各种layout,文本显示框,按钮,列表组件,复选框等等。有时间整理下这两个包下的类,梳理下,待续。。。

动画:

Android提供了几种动画类型:View Animation 、Drawable Animation 、Property Animation 。View Animation相当简单,不过只能支持对View进行简单的缩放、平移、旋转、透明度基本的动画,且有一定的局限性。逐帧动画就是多张图片一张一张的播放。属性动画是最新的,重点介绍下:

ValueAnimator是整个属性动画机制当中最核心的一个类,前面我们已经提到了,属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。它的内部使用一种时间循环的机制来计算值与值之间的动画过渡,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等,确实是一个非常重要的类。

相比于ValueAnimator,ObjectAnimator可能才是我们最常接触到的类,因为ValueAnimator只不过是对值进行了一个平滑的动画过渡,但我们实际使用到这种功能的场景好像并不多。而ObjectAnimator则就不同了,它是可以直接对任意对象的任意属性进行动画操作的,比如说View的alpha属性。

不过虽说ObjectAnimator会更加常用一些,但是它其实是继承自ValueAnimator的,底层的动画实现机制也是基于ValueAnimator来完成的,因此ValueAnimator仍然是整个属性动画当中最核心的一个类。那么既然是继承关系,说明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它们的用法也非常类似,这里如果我们想要将一个TextView在5秒中内从常规变换成全透明,再从全透明变换成常规,就可以这样写:

    ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
    animator.setDuration(5000);  
    animator.start();  

ofFloat()方法的第二个参数到底可以传哪些值呢?目前我们使用过了alpha、rotation、translationX和scaleY这几个值,分别可以完成淡入淡出、旋转、水平移动、垂直缩放这几种动画,那么还有哪些值是可以使用的呢?其实这个问题的答案非常玄乎,就是我们可以传入任意的值到ofFloat()方法的第二个参数当中。任意的值?相信这很出乎大家的意料吧,但事实就是如此。因为ObjectAnimator在设计的时候就没有针对于View来进行设计,而是针对于任意对象的,它所负责的工作就是不断地向某个对象中的某个属性进行赋值,然后对象根据属性值的改变再来决定如何展现出来

那么textview对象中是不是有alpha属性这个值呢?没有,不仅textview没有这个属性,连它所有的父类也是没有这个属性的!这就奇怪了,textview当中并没有alpha这个属性,ObjectAnimator是如何进行操作的呢?其实ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法,因此alpha属性所对应的get和set方法应该就是:

  1. public void setAlpha(float value);  
  2. public float getAlpha(); 

那么textview对象中是否有这两个方法呢?确实有,并且这两个方法是由View对象提供的,也就是说不仅TextView可以使用这个属性来进行淡入淡出动画操作,任何继承自View的对象都可以的。

既然alpha是这个样子,相信大家一定已经明白了,前面我们所用的所有属性都是这个工作原理,那么View当中一定也存在着setRotation()、getRotation()、setTranslationX()、getTranslationX()、setScaleY()、getScaleY()这些方法,不信的话你可以到View当中去找一下。

实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:

  • after(Animator anim)   将现有动画插入到传入的动画之后执行
  • after(long delay)   将现有动画延迟指定毫秒后执行
  • before(Animator anim)   将现有动画插入到传入的动画之前执行
  • with(Animator anim)   将现有动画和传入的动画同时执行
属性动画就简单说这么点,参考博客http://blog.csdn.net/guolin_blog/article/details/43536355,写的非常详细了。。。

消息队列:

   1.Message

       消息对象,顾名思义就是记录消息信息的类。这个类有几个比较重要的字段:

       a.arg1和arg2:我们可以使用两个字段用来存放我们需要传递的整型值,在Service中,我们可以用来存放Service的ID。

       b.obj:该字段是Object类型,我们可以让该字段传递某个多项到消息的接受者中。

       c.what:这个字段可以说是消息的标志,在消息处理中,我们可以根据这个字段的不同的值进行不同的处理,类似于我们在处理Button事件时,通过switch(v.getId())判断是点击了哪个按钮。

       在使用Message时,我们可以通过new Message()创建一个Message实例,但是Android更推荐我们通过Message.obtain()或者Handler.obtainMessage()获取Message对象。这并不一定是直接创建一个新的实例,而是先从消息池中看有没有可用的Message实例,存在则直接取出并返回这个实例。反之如果消息池中没有可用的Message实例,则根据给定的参数new一个新Message对象。通过分析源码可得知,Android系统默认情况下在消息池中实例化10个Message对象。

       2.MessageQueue

       消息队列,用来存放Message对象的数据结构,按照“先进先出”的原则存放消息。存放并非实际意义的保存,而是将Message对象以链表的方式串联起来的。MessageQueue对象不需要我们自己创建,而是有Looper对象对其进行管理,一个线程最多只可以拥有一个MessageQueue。我们可以通过Looper.myQueue()获取当前线程中的MessageQueue。

       3.Looper

       MessageQueue的管理者,在一个线程中,如果存在Looper对象,则必定存在MessageQueue对象,并且只存在一个Looper对象和一个MessageQueue对象。倘若我们的线程中存在Looper对象,则我们可以通过Looper.myLooper()获取,此外我们还可以通过Looper.getMainLooper()获取当前应用系统中主线程的Looper对象。在这个地方有一点需要注意,假如Looper对象位于应用程序主线程中,则Looper.myLooper()和Looper.getMainLooper()获取的是同一个对象。

       4.Handler

       消息的处理者。通过Handler对象我们可以封装Message对象,然后通过sendMessage(msg)把Message对象添加到MessageQueue中;当MessageQueue循环到该Message时,就会调用该Message对象对应的handler对象的handleMessage()方法对其进行处理。由于是在handleMessage()方法中处理消息,因此我们应该编写一个类继承自Handler,然后在handleMessage()处理我们需要的操作。

 

       另外,我们知道,Android UI操作并不是线程安全的,所以无法在子线程中更新UI。但Andriod提供了几种方法,可以在子线程中通知UI线程更新界面:

 

  • Activity.runOnUiThread( Runnable )
  • View.post( Runnable )
  • View.postDelayed( Runnable, long )
  • Handler

       比较常用的是通过Handler,用Handler来接收子线程发送的数据,并用此数据配合主线程更新UI。那么,只要在主线程中创建Handler对象,在子线程中调用Handler的sendMessage方法,就会把消息放入主线程的消息队列,并且将会在Handler主线程中调用该handler的handleMessage方法来处理消息。

此外,消息队列也可以做一些依次执行的事情,比如A-B-C-D依次执行,可以通过Handler来实现。

线程:

线程比计较复杂,涉及到线程池,线程同步,线程锁等一系列的概念,这里只能简单提一下:

ExecutorService executorService1 = Executors.newSingleThreadExecutor();

ExecutorService executorService2 = Executors.newFixedThreadPool(10);

ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
ExecutorService executorService4 = Executors.newCacheThreadPool();

  1. newCachedThreadPool()
    缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中。能reuse的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移出池。缓存型池子通常用于执行一些生存期很短的异步型任务 。
  2. newFixedThreadPool()
    fixedThreadPool与cacheThreadPool差不多,也是能reuse就用,但不能随时建新的线程 其独特之处:任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子。和cacheThreadPool不同:fixedThreadPool池线程数固定,但是0秒IDLE(无IDLE)。这也就意味着创建的线程会一直存在。所以fixedThreadPool多数针对一些很稳定很固定的正规并发线程,多用于服务器。
  3. newScheduledThreadPool()
    调度型线程池。这个池子里的线程可以按schedule依次delay执行,或周期执行 。0秒IDLE(无IDLE)。
  4. SingleThreadExecutor
    单例线程,任意时间池中只能有一个线程 。用的是和cache池和fixed池相同的底层池,但线程数目是1-1,0秒IDLE(无IDLE)。

线程池的关闭...

当我们不需要使用线程池的时候,我们需要对其进行关闭...有两种方法可以关闭掉线程池...

i.shutdown()...

  shutdown并不是直接关闭线程池,而是不再接受新的任务...如果线程池内有任务,那么把这些任务执行完毕后,关闭线程池....

ii.shutdownNow()

  这个方法表示不再接受新的任务,并把任务队列中的任务直接移出掉,如果有正在执行的,尝试进行停止...

线程管理中,主要就是同步,线程等待,唤醒等任务:

线程通讯:

    当使用synchronized 来修饰某个共享资源时(分同步代码块和同步方法两种情况),当某个线程获得共享资源的锁后就可以执行相应的代码段,直到该线程运行完该代码段后才释放对该共享资源的锁,让其他线程有机会执行对该共享资源的修改。当某个线程占有某个共享资源的锁时,如果另外一个线程也想获得这把锁运行就需要使用wait() 和notify()/notifyAll()方法来进行线程通讯了。
Java.lang.object 里的三个方法wait() notify()  notifyAll()


wait()

导致当前线程等待,直到其他线程调用同步监视器的notify方法或notifyAll方法来唤醒该线程。


wait(mills)

都是等待指定时间后自动苏醒,调用wait方法的当前线程会释放该同步监视器的锁定,可以不用notify或notifyAll方法把它唤醒。

notify()
唤醒在同步监视器上等待的单个线程,如果所有线程都在同步监视器上等待,则会选择唤醒其中一个线程,选择是任意性的,只有当前线程放弃对该同步监视器的锁定后,也就是使用wait方法后,才可以执行被唤醒的线程。

notifyAll()

唤醒在同步监视器上等待的所有的线程。只用当前线程放弃对该同步监视器的锁定后,也就是使用wait方法后,才可以执行被唤醒的线程。


内存泄漏:

Android 内存泄漏总结内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收。

1、非静态内部类的静态实例容易造成内存泄漏

    private static Drawable sBackground;    
    @Override    
    protected void onCreate(Bundle state) {    
        super.onCreate(state);    
        
        TextView label = new TextView(this);    
        label.setText("Leaks are bad");    
        
        if (sBackground == null) {    
            sBackground = getDrawable(R.drawable.large_bitmap);    
        }    
        label.setBackgroundDrawable(sBackground);    
        
        setContentView(label);    
    }   

以上例子的内存泄漏都是因为Activity的引用的生命周期超越了activity对象的生命周期。也就是常说的Context泄漏,因为activity就是context。

想要避免context相关的内存泄漏,需要注意以下几点:

·不要对activity的context长期引用(一个activity的引用的生存周期应该和activity的生命周期相同)

·如果可以的话,尽量使用关于application的context来替代和activity相关的context

·如果一个acitivity的非静态内部类的生命周期不受控制,那么避免使用它;正确的方法是使用一个静态的内部类,并且对它的外部类有一WeakReference,就像在ViewRootImpl中内部类W所做的那样。

2、注册某个对象后未反注册

注册广播接收器、注册观察者等等:

3、资源对象没关闭造成的内存泄露

资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。它们的缓冲不仅存在于Java虚拟机内,还存在于Java虚拟机外。如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄露。因为有些资源性对象,比如SQLiteCursor(在析构函数finalize(),如果我们没有关闭它,它自己会调close()关闭),如果我们没有关闭它,系统在回收它时也会关闭它,但是这样的效率太低了。因此对于资源性对象在不使用的时候,应该立即调用它的close()函数,将其关闭掉,然后再置为null.在我们的程序退出时一定要确保我们的资源性对象已经关

详细可以参考http://blog.csdn.net/gemmem/article/details/13017999,说的比较清楚

引起内存泄漏的原因很多,解决也比较复杂,一般开发工具会有工具支持分析内存使用情况,解决泄漏问题待续。。。

自定义view:

自定义view一般是继承view,通过重新绘制来实现一个view的过程,主要实现onDraw(绘制),onMeasure(测量),onLayout(摆放位置)等方法,完成绘制的过程。

在onDraw中可以直接用canvas,paint等来绘制,也可以绘制bitmap,绘制各种形状,甚至可以绘制文字等等。也可以对这些view添加动画。

至于组合控件比较简单,就是将多个view组合到一起,合并成一个整体的view向外提供。

可参考文章http://www.cnblogs.com/jiayongji/p/5560806.html,简单介绍了下自定义的view。

第三方框架:

okHttp、retrofit、RxJava、ButterKnife、Glide、Picasso

待续。。。

ViewPager+Fragment:

二者结合可以实现一般的底部导航,上面展示内容的需求,viewpager是v4包下的一个类,android.support.v4.view.ViewPager

Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of aPagerAdapter to generate the pages that the view shows.

ViewPager is most often used in conjunction with Fragment, which is a convenient way to supply and manage the lifecycle of each page. There are standard adapters implemented for using fragments with the ViewPager, which cover the most common use cases. These are FragmentPagerAdapter andFragmentStatePagerAdapter; each of these classes have simple code showing how to build a full user interface with them.

Views which are annotated with the ViewPager.DecorView annotation are treated as part of the view pagers 'decor'. Each decor view's position can be controlled via itsandroid:layout_gravity attribute. For example:

 <android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">

     <android.support.v4.view.PagerTitleStrip
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top" />

 </android.support.v4.view.ViewPager>
 

For more information about how to use ViewPager, readCreating Swipe Views with Tabs.

You can find examples of using ViewPager in the API 4+ Support Demos and API 13+ Support Demos sample code.

在Support4Demos里面有详细的使用例子,可以参考。

RecycleView:

listview的升级版,RecyclerView出现已经有一段时间了,可以通过导入support-v7对其进行使用。

RecyclerView的使用:整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。

RecylerView常见用法,包含了:

  • 系统提供了几种LayoutManager的使用;
  • 如何通过自定义ItemDecoration去设置分割线,或者一些你想作为分隔的drawable,注意这里
    巧妙的使用了系统的listDivider属性,你可以尝试添加使用divider和dividerHeight属性。
  • 如何使用ItemAnimator为RecylerView去添加Item移除、添加的动画效果。
  • 介绍了如何添加ItemClickListener与ItemLongClickListener。

可以看到RecyclerView可以实现:

详细请参考http://blog.csdn.net/lmj623565791/article/details/45059587

加密:


加密部分内容比较多,简单说下:

加密技术一般分为两类
1.对称加密,即加密与解密用的是同一把秘钥,常用的对称加密技术有DES,3DES,AES.
2.非对称加密,加密与解密用的是不同的秘钥,常用的非对称加密技术有RSA.

名词解释

   数字摘要:是将任意长度的消息变成固定长度的短消息,它类似于一个自变量是消息的函数,也就是Hash函数。数字摘要就是采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。

   DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

   3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。
该方法使用两个密钥,执行三次DES算法,加密的过程是加密-解密-加密,解密的过程是解密-加密-解密。

   AES:密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。是一种对称加密算法。

   SHA-1:安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。 SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。

   MD5:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

下面举例默认是用客户端(app)—服务器(server)通过http交互的。

对称加密:
优点:速度快
缺点:加密和解密的钥匙必须相同,只有通信双方才能知道密钥。

详解:当客户端或者服务器生成秘钥后,通过网络传输给对方,很容易被截取秘钥,(这就是 HTTP 传输所面临的问题之一:中间人攻击,指消息传递的过程中,处在传递路径上的攻击者可以嗅探或者窃听传输数据的内容。)不安全。当然有人考虑说,服务器跟客户端私下约定一个秘钥用于加解密,这样秘钥都是线下的,只有两端的开发人员知道,而且AES 在数学上保证了,只要你使用的 key 足够长,破解几乎是不可能的,但是万一密码泄露,app不能热更新的情况下,想要换秘钥是要很长的时间,这段时间内,损失不可估量。


非对称加密:
优点:算法更加复杂,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。
缺点:非对称加密算法的开销很大,所以如果直接以非对称技术来加密发送的消息效率会很差。

详解:客户端跟服务器都有两把秘钥,及公钥跟私钥。服务器用客户端的公钥加密的密文,只有用客户端的私钥才可以解密,同理,客户端用服务器的公钥加密的密文,只有服务器的私钥才可以解密,而服务器或者客户端的公钥可以公布出去,但是私钥都在各自手中,只有用他们自己的私钥才可以解密,保证安全。但是非对称加密效率差,所以有人提出如下把对称加密技术与非对称加密技术结合起来使用.

二:相关

HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数字签名,数字加密,Java,Servlet,Bouncy Castle

待续。。。

传感器:

在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用。

#define SENSOR_TYPE_ACCELEROMETER       1 //加速度
#define SENSOR_TYPE_MAGNETIC_FIELD      2 //磁力
#define SENSOR_TYPE_ORIENTATION         3 //方向
#define SENSOR_TYPE_GYROSCOPE           4 //陀螺仪
#define SENSOR_TYPE_LIGHT               5 //光线感应
#define SENSOR_TYPE_PRESSURE            6 //压力
#define SENSOR_TYPE_TEMPERATURE         7 //温度 
#define SENSOR_TYPE_PROXIMITY           8 //接近
#define SENSOR_TYPE_GRAVITY             9 //重力
#define SENSOR_TYPE_LINEAR_ACCELERATION 10//线性加速度
#define SENSOR_TYPE_ROTATION_VECTOR     11//旋转矢量
现在的传感器应该更多了,关于传感器的一些知识,简单介绍下:

Android传感器按大方向划分大致有这么三类传感器:动作(Motion)传感器、环境(Environmental)传感器、位置(Position)传感器。

动作传感器

加速(accelerometer)传感器、重力(gravity)传感器、陀螺仪(gyroscope)传感器、旋转向量(rotational vector )传感器

环境传感器

湿度(barometer)传感器、光线(photometer)传感器、温度(thermometer)传感器

位置传感器

方向(orientation)传感器、磁力(magnetometer)传感器

具体传感器可以参考http://blog.csdn.net/smartbetter/article/details/53161452,讲解比较详细了,或者参考官方文档

缓存策略:

Android缓存:

采用缓存,可以进一步大大缓解数据交互的压力,又能提供一定的离线浏览。下边我简略列举一下缓存管理的适用环境:

1. 提供网络服务的应用

2. 数据更新不需要实时更新,哪怕是3-5分钟的延迟也是可以采用缓存机制。

3. 缓存的过期时间是可以接受的(类似网易的新闻阅读,支持离线离线阅读)

这样所带来的好处:

1. 减小服务器的压力

2. 提高客户端的响应速度(本地数据提取嘛)

3. 一定程度上支持离线浏览(可以参考网易的那个新闻应用,个人感觉离线阅读做得非常棒。)

平时所谓的三级缓存,其实是内存,本地,网络三级。

关于缓存,可以参考文章:http://blog.csdn.net/zxw136511485/article/details/52153287



 至于设计模式,混合开发等,待续。。。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程设计报告书 课程名称: 操作系统原理 题 目: 基于Android系统的音乐播放器设计与实现 2012 年 7 月 5 日 课程设计任务书 设计题目:基于Android 系统的音乐播放器设计与实现 初始条件: Linux操作系统,Android开发环境,Java编译环境,SQLite数据库 要求完成的主要任务: 主要任务: 现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的目的是 开发一个可以播放主流音乐文件格式的播放器的播放功能模块,要求音乐播放器能够播 放Mp3,Wav多种格式的音乐文件,能够控制播放,暂停,停止,上一曲,下一曲,能够 调节音量,能播放RMVB格式的视频文件,此外,还能支持中文、英文等语言界面。要求 视觉外观美观,操作简单。 本项目是一款基于Android手机平台的音乐播放器的子模块,使Android手机拥有个性 的多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处 于音乐视频的旋律之中。使人们的生活更加多样化。也使设计者更加熟练Android的技术 和其它在市场上的特点 设计报告撰写格式要求: 1设计题目与要求 2 设计思想 3系统结构 4 数据结构的说明和模块的算法流程图 5 使用说明书(即用户手册):内容包含如何登录、退出、读、写等操作说明 6 运行结果和结果分析(其中包括实验的检查结果、程序的运行情况) 7 自我评价与总结 8 附录:程序清单,注意加注释(包括关键字、方法、变量等),在每个模块前加注释; 时间安排 7月1日 布置课程设计任务;分配题目后,查阅资料、 准备程序; 7月 2~7月4 日上机调试程序、书写课程设计报告; 7月5 日 提交课程设计报告及相关文档。 基于Android平台的音乐播放器的播放控制功能设计 摘要Android简介: Android是一种以Linux为基础的开放源码操作系统,主要使用于便携设备。目前尚未 有统一中文名称,中国大陆地区较多人使用"安卓"或"安致"。Android操作系统最初由A ndy Rubin开发,最初主要支持手机。2005年由Google收购注资,并组建开放手机联盟开发改 良,逐渐扩展到平板电脑及其他领域上。 Android平台五大优势特色: 1、开放性 2、挣脱运营商的束缚 3、丰富的硬件选择 4、不受任何限制的开发商 5、无缝结合的Google应用  图 Android 软件体系结构图 Android作为一个移动设备的平台,其软件层次结构包括了一个操作系统(OS),中间件 (MiddleWare)和应用程序(Application)。根据Android的软件框图,其软件层次结 构自下而上分为以下几个层次: 第一、操作系统层(OS) 第二、各种库(Libraries)和Android 运行环境(RunTime) 第三、应用程序框架(Application Framework) 第四、应用程序(Application) 1、设计题目与要求 题目:基于Android平台的音乐播放器的播放控制功能设计 要求:现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,本项目的 目的是开发一个可以播放主流音乐文件格式的播放器的播放功能模块,要求音乐播放器 能够播放Mp3,Wav多种格式的音乐文件,能够控制播放,暂停,停止,上一曲,下一曲 ,能够调节音量,能播放RMVB格式的视频文件,此外,还能支持中文、英文等语言界面 。要求视觉外观美观,操作简单。 本项目是一款基于Android手机平台的音乐播放器的子模块,使Android手机拥有个性 的多媒体播放器,使手机显得更生动灵活化,与人们更为接近,让手机主人随时随地处 于音乐视频的旋律之中。使人们的生活更加多样化。也使设计者更加熟练Android的技术 和其它在市场上的特点。 2、设计思想 要实现这个音乐播放器。首先应该考虑到的就是他的功能,要有后台播放功能以及显 示正在播放的文件和把手机中的音乐文件以列表的形式显示在手机上,这就要使用到li stview类。 另外在本地歌曲列表和正在播放的歌曲之间要进行动态菜单的跳转故而想到用tabho st这个容器进行布局。后台播放创建一个类继承service方法,在该类中使其具有播放暂 停下一首上一首的功能的方法,从而是它在各个Activity之间进行跳转的时候为其他的 类提供相应的方法。创建一个新建文件类和过滤文件信息的类,用以存贮特定的文件信 息和当用户改变文件夹终不改的内容的时候同步更新播放列表。于接打电话这个问题, 创建一个类进行监听,当电话进来或出去的时候调用service方法停止音乐播放并记下播 放点。 对于刚接触Android开发的我们,在很多的知识点上还是不是很理解,鉴于此在制作 的过程难免会遇到各种问题,解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值