Android 5.0(Lollipop)适配指南

本文介绍了HTTP协议的发展历程,从HTTP0.9到HTTP3.0的主要版本特点,并对比了HTTPS与HTTP的区别。深入探讨了各版本间的改进,如长连接、多路复用等关键特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 5.0 (Lollipop) 是 Android 平台的一个重要版本,带来了许多新特性和变更。本文将详细介绍 Android 5.0 的核心更新及其适配方法,并配以图解和代码示例。


主要变更概览

1. Material Design

Android 5.0 引入了 Material Design,这是一套全新的设计语言,为用户提供了一致的、直观的交互体验。

核心特性:

  • 界面动画与过渡效果
  • 阴影和光照
  • 调色板和主题支持

图解:Material Design 元素

代码示例:实现基本 Material Design 样式
<!-- styles.xml -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="colorPrimary">#6200EE</item>
    <item name="colorPrimaryDark">#3700B3</item>
    <item name="colorAccent">#03DAC5</item>
</style>
// Kotlin 示例
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener {
    Snackbar.make(it, "Hello Material Design!", Snackbar.LENGTH_LONG).show()
}

2. ART Runtime

Android 5.0 默认启用了 ART(Android Runtime)替代 Dalvik,提升了应用性能和响应速度。

适配建议
  • 确保应用支持 ART。
  • 避免依赖运行时特定行为,如直接修改字节码。

3. 新的通知系统

通知系统在 Android 5.0 进行了重大更新,支持锁屏通知和优先级管理。

图解:通知优先级

代码示例:创建优先级通知
val builder = NotificationCompat.Builder(this, "default")
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("通知标题")
    .setContentText("这是通知内容")
    .setPriority(NotificationCompat.PRIORITY_HIGH)

with(NotificationManagerCompat.from(this)) {
    notify(1, builder.build())
}
适配建议
  • 测试通知在锁屏上的显示效果。
  • 使用 NotificationChannel 管理不同类型的通知(从 Android 8.0 开始支持)。

4. JobScheduler API

引入了 JobScheduler API,用于高效地管理后台任务。

图解:JobScheduler 工作流

代码示例:使用 JobScheduler
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val jobInfo = JobInfo.Builder(1, ComponentName(this, MyJobService::class.java))
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    .setPeriodic(15 * 60 * 1000) // 每 15 分钟执行一次
    .build()
jobScheduler.schedule(jobInfo)

5. RecyclerView 和 CardView

Android 5.0 引入了 RecyclerView 和 CardView,作为 ListView 和 GridView 的替代品,提供更强大的功能。

图解:RecyclerView 结构

代码示例:使用 RecyclerView
  1. 添加依赖:
dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.0"
    implementation "androidx.cardview:cardview:1.0.0"
}
  1. 实现 RecyclerView Adapter:
class MyAdapter(private val dataset: List<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    class MyViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val textView = LayoutInflater.from(parent.context)
            .inflate(R.layout.text_row_item, parent, false) as TextView
        return MyViewHolder(textView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.textView.text = dataset[position]
    }

    override fun getItemCount() = dataset.size
}

6. Vector Drawables

支持矢量图形(Vector Drawable),提升了图像的可伸缩性和质量。

示例:定义矢量图形
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M12,2L15.09,8.26L22,9.27L17,14.14L18.18,21.02L12,17.77L5.82,21.02L7,14.14L2,9.27L8.91,8.26L12,2z"/>
</vector>

适配建议

  1. Material Design 主题适配

    • 使用 Theme.MaterialComponents
    • 更新旧组件为 ToolbarFloatingActionButton
  2. 通知测试

    • 测试在不同锁屏设置下的表现。
  3. RecyclerView 替代 ListView

    • 优化复杂列表的性能。
  4. 矢量图支持

    • build.gradle 中启用 vectorDrawables.useSupportLibrary = true

 webview适配

  • 不允许加载混合内容,也就是说https的网页内不允许加载http资源,反之依然

android5.0以下版本,WebView.getSettings().getMixedContentMode()的默认值为MIXED_CONTENT_ALWAYS_ALLOW,也就是总是允许加载混合内容。android5.0起,这个值默值为MIXED_CONTENT_NEVER_ALLOW。处于安全考虑,一般情况下,强烈建议使用MIXED_CONTENT_NEVER_ALLOW模式。但是,如果该网页为第三方网页或者我们的https网页中加载了第三方资源,我们不太可能立马要求对方升级为https。那么我们就做如下适配:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    mWebView.getSettings()
            .setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
  • 不允许写入第三方cookie

android5.0起,默认不允许写入第三方cookie,需手动设置:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView,true);
}
  • 不再一次性渲染整个网页

android5.0以前,webview总是一次性渲染整个网页。android5.0以后实行只能渲染,只保证可视部分是已渲染的。这在某些场合可能会出问题,比如为webview截屏。当试图在5.0上对webview截屏时会发现只截取到可视部分,并没有截取整个网页。当然,这种情况发生在你并没有上下滑动webview使其整个网页得到渲染。

通过在创建webview前调用静态方法WebView.enableSlowWholeDocumentDraw()使其总是一次性渲染整个网页。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            WebView.enableSlowWholeDocumentDraw();
        }
        setContentView(R.layout.activity_main);
    }

}
  • webview选择文件时WebChromeClient回调方法的改变
mWebView.setWebChromeClient(new WebChromeClient() {

    // when sdk version < 3.0
    public void openFileChooser(ValueCallback<Uri> valueCallback) {
    
    }

    // when sdk version  >= 3.0
    public void openFileChooser(ValueCallback valueCallback, String acceptType) {
    
    }

    //when sdk version  >= 4.1
    public void openFileChooser(ValueCallback<Uri> valueCallback,
                                String acceptType, String capture) {
    }

    // when sdk version >= 5.0
    @Override
    public boolean onShowFileChooser(WebView webView,
                                     ValueCallback<Uri[]> filePathCallback,
                                     WebChromeClient.FileChooserParams fileChooserParams) {
        return true;
    }
});

在android5.0以前,我们在Web页面上点击选择文件的控件(<input type="file">)时,会回调WebChromeClient的openFileChooser方法,不过该方法的形参在android3.0以前、3.0及以后、4.1及以后有所变化。到了android5.0,直接剔除了该方法,以onShowFileChooser代之。这将导致在5.0以下版本运行时,无法在onShowFileChooser方法中处理回调。openFileChooser方法不要标注@Override,由于是直接剔除,在高版本的sdk找不到该方法,如果你的编译版本>=5.0那么将编译报错。可根据你的minSdkVersion选择性地加入openFileChooser的三个历史版本。

Service适配

android5.0之前,我们可以隐式启动一个Service,

Intent intent = new Intent().setAction("com.android.test.for.service");
startService(intent);

android5.0及以后,隐式启动Service,程序会崩溃。

所以,在android5.0及以后必须显示调用Service。两种方式:

  • 指定packageName
Intent intent = new Intent()
        .setAction("com.android.test.for.service")
        .setPackage(getPackageName());
startService(intent);
  • 直接指定具体的Service类
Intent intent = new Intent(this, MyService.class);
startService(intent);

结论

Android 5.0 带来了许多变革,为开发者提供了更强大的工具和 API。同时也要求开发者在适配过程中注意新旧版本兼容问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vincent(朱志强)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值