Android 5.0行為變更
API級別:21
Android Runtime(ART)
在 Android 5.0 中,ART 運行時取代 Dalvik 成為平臺默認設置烟很。Android 4.4 中已引入處于實驗階段的 ART 運行時颈墅。
有關 ART 的新功能概述毒坛,請參閱 ART 簡介末融。部分主要的新功能包括: 預先 (AOT) 編譯,改進的垃圾回收 (GC)酪刀,改進的調試支持粹舵。
ART與Dalvik的區(qū)別
程序運行的過程中,Dalvik虛擬機在不斷的進行將字節(jié)碼編譯成機器碼的工作骂倘。ART引入了AOT這種預編譯技術眼滤,在應用程序安裝的過程中,ART就已經將所有的字節(jié)碼重新編譯成了機器碼历涝。應用程序運行過程中無需進行實時的編譯工作诅需,只需要進行直接調用.因此,ART極大的提高了應用程序的運行效率荧库,同時也減少了手機的電量消耗堰塌,提高了移動設備的續(xù)航能力,在垃圾回收等機制上也有了較大的提升分衫。
相對于Dalvik虛擬機模式场刑,ART模式下Android應用程序的安裝需要消耗更多的時間,同時也會占用更大的儲存空間(指內部儲存蚪战,用于儲存編譯后的代碼),但節(jié)省了很多Dalvik虛擬機用于實時編譯的時間牵现。
大多數 Android 應用無需任何更改就可以在 ART 下工作。不過邀桑,部分適合 Dalvik 的技術并不適用于 ART瞎疼。如需了解有關最重要問題的信息,請參閱在 Android Runtime (ART) 上驗證應用行為壁畸。如存在以下情況贼急,應特別注意:
- 您的應用使用 Java 原生接口 (JNI) 運行 C/C++ 代碼。
- 您使用生成非標準代碼的開發(fā)工具(例如瓤摧,一些代碼混淆工具)。
- 您使用與壓縮垃圾回收不兼容的技術玉吁。
Material Design 樣式
- 概念:融合卡片式照弥,立體式的設計風格,強調層次感,動畫进副,陰影等元素
- 國內翻譯介紹:查看 http://design.1sters.com
- 官網介紹:http://developer.android.com/training/material
- 演示Android5.0 Demo
- Android UI樣式風格發(fā)展:2.3版本(黃色丑陋版)->4.0(Holo)->5.0(MaterialDesign)
動態(tài)替換Theme
修改狀態(tài)欄这揣,ActionBar悔常,界面背景,NavigationBar的顏色给赞。讓Activity使用自定義的Theme机打。
<style name="AppTheme" parent="@android:style/Theme.Material">
<!--狀態(tài)欄顏色-->
<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>
動態(tài)替換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以及背景色可以讓界面色調實現統(tǒng)一,使用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對象后,獲取其中的顏色盆耽,顏色對應如下:
使用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如何顯示布局,系統(tǒng)提供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;
}
//動態(tài)請求權限
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 效率更高责嚷,因為它可以通過透明壓縮和響應緩存減少網絡使用,并可最大限度降低耗電量掂铐。要繼續(xù)使用 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添加文本變化監(jiān)聽器:
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) {
}
});
實現效果:
CoordinatorLayout的使用
CoordinatorLayout作為“super-powered FrameLayout”基本實現兩個功能:
- 作為頂層布局
- 調度協(xié)調子布局
與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();
}
});
實現效果:
與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>
效果:
具體還有很多用法堡纬,這里不一一介紹聂受,參考: CoordinatorLayout的使用
Android 7.0行為變更
API級別:24
新的Notification
Android N 添加了很多新的notifications API,進行了又一次的設計烤镐,引入了新的風格蛋济。
- 模板更新: 開發(fā)人員將能夠充分利用新模板,僅僅需進行少量的代碼調整炮叶。
- 消息樣式自己定義: 新增自己定義樣式碗旅、消息回復、消息分組等更加靈活镜悉。
- 捆綁通知: 系統(tǒng)能夠將消息組合在一起(比如祟辟,按消息主題)并顯示組。用戶能夠適當地進行 Dismiss 或 Archive 等操作侣肄。
- 直接回復: 對于實時通信應用旧困。Android 系統(tǒng)支持內聯回復,以便用戶能夠直接在通知界面中高速回復短信稼锅。
- 自己定義視圖: 兩個新的 API 吼具,在通知中使用自己定義視圖時能夠充分利用系統(tǒng)裝飾元素,如通知標題和操作矩距。
Project Svelte:后臺優(yōu)化
Project Svelte在持續(xù)改善拗盒,以最大程度降低生態(tài)系統(tǒng)中一系列 Android 設備中系統(tǒng)和應用使用的 RAM。在 Android N 中锥债,Project Svelte 注重優(yōu)化在后臺中運行應用的方式陡蝇。
Android N 刪除了三項隱式廣播(CONNECTIVITY_ACTION、ACTION_NEW_PICTURE 和ACTION_NEW_VIDEO) 哮肚。以幫助優(yōu)化內存使用和電量消耗登夫。
權限更改
隨著Android版本號越來越高,Android對隱私的保護力度也越來越大允趟。
從Android6.0引入的動態(tài)權限控制(Runtime Permissions)到Android7.0的“私有文件夾被限制訪問”恼策,“StrictMode API 政策”。這些更改在為用戶帶來更加安全的操作系統(tǒng)的同一時候也為開發(fā)人員帶來了一些新的任務拼窥。怎樣讓你的APP能夠適應這些改變而不是cash戏蔑,是擺在每一位Android開發(fā)人員身上的責任。
文件夾被限制訪問,應用間共享文件
在Android7.0系統(tǒng)上鲁纠。Android 框架強制運行了 StrictMode API 政策禁止向你的應用外公開 file:// URI总棵。
假設一項包含文件 file:// URI類型 的 Intent 離開你的應用,應用失敗改含,并出現 FileUriExposedException 異常情龄,如調用系統(tǒng)相機拍照,或裁切照片捍壤。
解決方法:
第一步:在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)文件夾下創(chuàng)建一個xml文件夾,然后創(chuàng)建一個名為“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了。
以調用系統(tǒng)相機拍照為例斑鼻,我們須要將上述拍照代碼改動為例如以下:
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創(chuàng)建一個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);