Android 5.0 6.0 7.0 新特性

Android 5.0行为变更

API级别:21

Android Runtime(ART)

在 Android 5.0 中,ART 运行时取代 Dalvik 成为平台默认设置。Android 4.4 中已引入处于实验阶段的 ART 运行时。
有关 ART 的新功能概述,请参阅 ART 简介。部分主要的新功能包括: 预先 (AOT) 编译,改进的垃圾回收 (GC),改进的调试支持。
ART与Dalvik的区别
程序运行的过程中,Dalvik虚拟机在不断的进行将字节码编译成机器码的工作。ART引入了AOT这种预编译技术,在应用程序安装的过程中,ART就已经将所有的字节码重新编译成了机器码。应用程序运行过程中无需进行实时的编译工作,只需要进行直接调用.因此,ART极大的提高了应用程序的运行效率,同时也减少了手机的电量消耗,提高了移动设备的续航能力,在垃圾回收等机制上也有了较大的提升。
相对于Dalvik虚拟机模式,ART模式下Android应用程序的安装需要消耗更多的时间,同时也会占用更大的储存空间(指内部储存,用于储存编译后的代码),但节省了很多Dalvik虚拟机用于实时编译的时间。

ART与Dalvik的区别.jpg

大多数 Android 应用无需任何更改就可以在 ART 下工作。不过,部分适合 Dalvik 的技术并不适用于 ART。如需了解有关最重要问题的信息,请参阅在 Android Runtime (ART) 上验证应用行为。如存在以下情况,应特别注意:

  • 您的应用使用 Java 原生接口 (JNI) 运行 C/C++ 代码。
  • 您使用生成非标准代码的开发工具(例如,一些代码混淆工具)。
  • 您使用与压缩垃圾回收不兼容的技术。

Material Design 样式

动态替换Theme

修改状态栏,ActionBar,界面背景,NavigationBar的颜色。让Activity使用自定义的Theme。

<style name="AppTheme" parent="@android:style/Theme.Material">
    <!--状态栏颜色-->
    <item name="android:colorPrimaryDark">#f00</item>
    <!--ActionBar颜色-->
    <item name="android:colorPrimary">#ff0</item>
    <!--界面背景颜色-->
    <item name="android:windowBackground">@color/colorWindowBackground</item>
    <!--导航栏颜色-->
    <item name="android:navigationBarColor">#00f</item>
</style>

动态替换Theme的步骤:
1.定义至少2套theme
2.调用setTheme方法设置当前的theme,但是该方法要在setContentView之前,如:

setTheme(mTheme);
setContentView(R.layout.activity_main);

设置了Theme,需要finish当前Activity,然后重启当前Activity,让Theme生效

Intent intent = getActivity().getIntent();
getActivity().finish();//结束当前的Activity
getActivity().overridePendingTransition(0,0);//不要动画
startActivity(intent);

Palette的使用

使用Palette可以让我们从一张图片中拾取颜色,将拾取到的颜色赋予ActionBar,StatusBar以及背景色可以让界面色调实现统一,使用Palette需要添加以下依赖:

compile 'com.android.support:palette-v7:23.0.0+'

Palette提供的API
传入Bitmap即可获取Palette对象,以下是同步和异步使用方式:

//同步获取,需要在子线程中使用
Palette palette = Palette.from(drawable.getBitmap()).generate();
//异步获取,可以在主线程中使用
Palette.from(drawable.getBitmap()).generate(new Palette.PaletteAsyncListener() {
    @Override
    public void onGenerated(Palette palette) {
        //...
    }
});

得到Palette对象后,获取其中的颜色,颜色对应如下:


颜色对应.jpg

使用palette获取指定颜色:

palette.getLightMutedColor(defaultColor);

也可以先获取采样对象Swatch,从Swatch中获取我们需要的颜色:

//获取有活力颜色的采样对象
Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
采样对象Swatch提供了以下方法来获取颜色:
//swatch.getPopulation(): the amount of pixels which this swatch represents.
//swatch.getRgb(): the RGB value of this color.
//swatch.getHsl(): the HSL value of this color,即色相,饱和度,明度.
//swatch.getBodyTextColor(): the RGB value of a text color which can be displayed on top of this color.
//swatch.getTitleTextColor(): the RGB value of a text color which can be displayed on top of this color
//一般会将getRgb设置给控件背景色,getBodyTextColor()设置给文字颜色
textView.setBackgroundColor(vibrantSwatch.getRgb());
textView.setTextColor(vibrantSwatch.getBodyTextColor());

CardView的使用

CardLayout拥有高度和阴影,以及轮廓裁剪,圆角等功能。
各属性说明:

  • 设置圆角:card_view:cardCornerRadius="10dp"
  • 设置高度:card_view:cardElevation="10dp"
  • 设置内边距:card_view:contentPadding="10dp"
  • 设置背景色:card_view:cardBackgroundColor="?android:attr/colorPrimary"

RecyclerView的使用

  • https://developer.android.com/intl/zh-tw/training/material/lists-cards.html
  • 先添加依赖 compile 'com.android.support:recyclerview-v7:23.1.1'
  • 设置LayoutManager:控制RecyclerView如何显示布局,系统提供3个布局管理器:
    • LinearLayoutManager:线性布局,有横向和竖直方向显示
    • GridLayoutManager:网格布局,有横向和竖直方向显示
    • StaggeredGridLayoutManager: 瀑布流布局,有横向和竖直方向显示
  • 然后给RecyclerView设置Adapter<RecyclerView.ViewHolder>
  • 设置点击事件,由于RecyclerView没有setOnItemClickListener,只能在Adapter中给View设置Click事件。

ToolBar的使用

它用来代替ActionBar,但是比ActionBar更加灵活,相当于可以写在布局文件中的ActionBar;与DrawerLayout的使用的时候,DrawerLayout可以覆盖在ToolBar上,并且ToolBar和ActionBar不能同时使用
使用ToolBar的步骤:
先隐藏ActionBar,可以继承一个不带ActionBar的Theme,如:

style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"

然后在Activity中设置ToolBar替代ActionBar:

setSupportActionBar(toolBar);

最后设置ToolBar的显示内容:

toolBar.setTitle("ToolBar");//设置标题
toolBar.setNavigationIcon(iconRes);//设置图标
toolBar.setOnMenuItemClickListener();//设置Menu Item点击

Android 6.0行为变更

API级别:23

运行时权限

对于以 Android 6.0(API 级别 23)或更高版本为目标平台的应用,请务必在运行时检查和请求权限。其中:

  • 新的方法checkSelfPermission()可以用来判断你的应用是否被授予了权限。
  • 而requestPermissions()可请求权限。
//判断是否授予某个权限
public static boolean hasPermission(@NonNull Context context, @NonNull String... permissions) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }

        for (String permission : permissions) {
            boolean hasPermission = (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED);
            if (!hasPermission) {
                return false;
            }
        }
        return true;
    }
//动态请求权限
 public static void requestPermissions(Object o, int requestCode, String... permissions) {
        if (o instanceof Activity) {
            ActivityCompat.requestPermissions(((Activity) o), permissions, requestCode);
        } else if (o instanceof android.support.v4.app.Fragment) {
            ((android.support.v4.app.Fragment) o).requestPermissions(permissions, requestCode);
        }
    }

取消支持Apache HTTP客户端

Android 6.0 版移除了对 Apache HTTP 客户端的支持。如果您的应用使用该客户端,并以 Android 2.3(API 级别 9)或更高版本为目标平台,请改用 HttpURLConnection 类。此 API 效率更高,因为它可以通过透明压缩和响应缓存减少网络使用,并可最大限度降低耗电量。要继续使用 Apache HTTP API,您必须先在 build.gradle 文件中声明以下编译时依赖项:

android {
    useLibrary 'org.apache.http.legacy'
}

6.0新控件

使用需要依赖design类库:

compile 'com.android.support:design:23.0.0+'
TextInputLayout的使用

先在TextInputLayout中包裹一个EditText,如:

 <android.support.design.widget.TextInputLayout
            android:textColorHint="#fff"
            android:id="@+id/username"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <EditText
                android:textColor="#fff"
                android:id="@+id/edt_user"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="user" />
        </android.support.design.widget.TextInputLayout>

然后给EditText添加文本变化监听器:

editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String name = username.getEditText().getText().toString();
                //例如用户名必须包含 字母a
                if (!name.contains("a")) {
                    username.setError("Not a valid user name!");
                }else {
                    username.setErrorEnabled(false);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

实现效果:


TextInputLayout输入框效果图.gif
CoordinatorLayout的使用

CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能:

  • 作为顶层布局
  • 调度协调子布局

与FloatingActionButton结合使用
定义布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/ic_done" />
</android.support.design.widget.CoordinatorLayout>

activity:

 findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view,"FAB",Snackbar.LENGTH_LONG)
                        .setAction("cancel", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                //这里的单击事件代表点击消除Action后的响应事件
                            }
                        })
                        .show();
            }
        });

实现效果:

fab效果.gif

与AppBarLayout结合使用
定义布局:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done" />

</android.support.design.widget.CoordinatorLayout>

效果:

tab效果.gif

具体还有很多用法,这里不一一介绍,参考: CoordinatorLayout的使用

Android 7.0行为变更

API级别:24

新的Notification

Android N 添加了很多新的notifications API,进行了又一次的设计,引入了新的风格。

  • 模板更新: 开发人员将能够充分利用新模板,仅仅需进行少量的代码调整。
  • 消息样式自己定义: 新增自己定义样式、消息回复、消息分组等更加灵活。
  • 捆绑通知: 系统能够将消息组合在一起(比如,按消息主题)并显示组。用户能够适当地进行 Dismiss 或 Archive 等操作。
  • 直接回复: 对于实时通信应用。Android 系统支持内联回复,以便用户能够直接在通知界面中高速回复短信。
  • 自己定义视图: 两个新的 API ,在通知中使用自己定义视图时能够充分利用系统装饰元素,如通知标题和操作。

Project Svelte:后台优化

Project Svelte在持续改善,以最大程度降低生态系统中一系列 Android 设备中系统和应用使用的 RAM。在 Android N 中,Project Svelte 注重优化在后台中运行应用的方式。
Android N 删除了三项隐式广播(CONNECTIVITY_ACTION、ACTION_NEW_PICTURE 和ACTION_NEW_VIDEO) 。以帮助优化内存使用和电量消耗。

权限更改

随着Android版本号越来越高,Android对隐私的保护力度也越来越大。
从Android6.0引入的动态权限控制(Runtime Permissions)到Android7.0的“私有文件夹被限制訪问”,“StrictMode API 政策”。这些更改在为用户带来更加安全的操作系统的同一时候也为开发人员带来了一些新的任务。怎样让你的APP能够适应这些改变而不是cash,是摆在每一位Android开发人员身上的责任。

文件夹被限制訪问,应用间共享文件

在Android7.0系统上。Android 框架强制运行了 StrictMode API 政策禁止向你的应用外公开 file:// URI。
假设一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常,如调用系统相机拍照,或裁切照片。
解决方法:
第一步:在manifest清单文件里注冊provider

        <!-- exported:要求必须为false,为true则会报安全异常。 -->
        <!-- grantUriPermissions:true,表示授予 URI 临时访问权限。 -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.huayun.onenotice.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

第二步:指定共享的文件夹
为了指定共享的文件夹我们须要在资源(res)文件夹下创建一个xml文件夹,然后创建一个名为“filepaths”(名字能够随便起,仅仅要和在manifest注冊的provider所引用的resource保持一致就可以)的资源文件。内容例如以下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!-- root-path 手机存储根目录 -->
    <!-- external-path:sd ;path:你的应用保存文件的根目录;name随便定义-->
    <external-path path="" name="camera_photos" />
</paths>

第三步:使用FileProvider
上述准备工作做完之后,如今我们就能够使用FileProvider了。
以调用系统相机拍照为例,我们须要将上述拍照代码改动为例如以下:

File file=new File(Environment.getExternalStorageDirectory(), "/temp/"+System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists())file.getParentFile().mkdirs();
      Uri imageUri = FileProvider.getUriForFile(context, "com.jph.takephoto.fileprovider", file);//通过FileProvider创建一个content类型的Uri
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //加入这一句表示对目标应用暂时授权该Uri所代表的文件
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//将拍取的照片保存到指定URI
startActivityForResult(intent,1000);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容