我对Android学习的一些看法------追求本真的味道

来源:互联网 发布:qq电脑软件管家 编辑:程序博客网 时间:2024/04/30 01:45

        虽然做Android开发已经有一段时间了,但是很少写博客一类的东西。今天算是第一次真正意义上在CSDN平台上发表自己的一些看法,心里既有欣喜,也有一些压力。欣喜在于,能将自己的想法公之与众,并且能够和大家一起交流技术上的东西。压力在于,自己要能够将一些较高质量的作品奉献给大家。闲话先说到这,来谈谈我对Android开发的一些理解吧。

一、重理论,多实践

Android中的多层架构极具拓展性。里面也包含很多的机制,例如Bind机制,Handler机制等等。但是我们最熟悉的应该就是Android的四大组件了,Activity,Broadcast Receiver,Service,Content Provider.而这四大组件又通过Intent这一个纽带去传递数据,进行连接的。这其中的一些机制,究竟是怎样实现的呢,又运用了什么样的设计模式呢,这是我们需要探究的问题。当然要清楚地知道其中的原理,需要有一定的功力,也即要有一定的理论基础,才能明白其中的一些巧妙之处。

要想深入得理解Android的设计理论知识。首先得知道怎样去使用Android的四大组件。让我们简单的看一下吧。

1.Activity

最最重要的一大组件就是Activity了。

我们可以看到Activity的7个生命周期以及相互之间的转换关系。十分明确一个Activity处于生命周期的哪个部分,才能够帮助我们更好地利用生命周期,在不同的时间段去干不同的事情。例如一些特殊情况,譬如按下Home键时,当前的Activity会被挂到任务栈的后台,Activity会执行onPause()和onStop()方法。当用户重新点开这个APP时,会执行onRestart()方法,然后执行onStart()方法,onResume()方法,直至运行状态。当Activity处于后台时,除非系统内存不足,否则是不会杀死这个Activity所在的进程的。还有当手机屏幕进行切屏时,Activity会被销毁并且重新创建;整个生命周期会从这是一定要注意将系统的状态保存。。。等等一系列的问题。

另外一个重要的事情是,Activity为我们提供了4种启动模式,帮助我们去设置不同的Activity状态,当然这4种启动模式都是基于对Activity回退栈(Back Stack)的处理。四种启动模式分别是Standard,SingleTop,SingleTask,SingleInstance。这四种启动模式相信大家都知道,但是应该在什么时候,选择哪种模式呢。这里给出我的一些理解给大家参考。

Standard:是个富二代,去超市里,看到什么玩具就要什么玩具,不管家里有没有,而长辈都会一直给他买的。而且Google API中默认大伙都是富二代

SingleTop:家里有点钱,孩子刚刚买过的玩具,就不会再买了,孩子要的时候,直接拿给他用。但是如果孩子的玩具已经玩旧,父母会立马给孩子买新的。

SingleTask:家里条件一般般。小孩要玩玩具的时候,只要家里有,就不会买新的,哪怕玩具放在箱子的最里面,父母也会把玩具上面的东西全部扔掉,直至拿到玩具。(这是绝对地溺爱啊)

SingleInstance:家里最贫穷的,但是自由。小孩也是任性的,想要什么玩具,就让父母造,父母也是很细心,造好的玩具都一一存放好(不放在一起)。孩子要玩,只要有,就能很快拿给他,没有的话,就再造一个。(感觉和富二代是两种完全不同的生活)

当然,以上都是戏说这个回退栈的,仅供大家参考。官方的描述是这样的:

"standard"(默认模式)
默认。系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。
"singleTop"
如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例(但前提是位于返回栈顶部的 Activity 并不是 Activity 的现有实例)。

例如,假设任务的返回栈包含根 Activity A 以及 Activity B、C 和位于顶部的 D(堆栈是 A-B-C-D;D 位于顶部)。收到针对 D 类 Activity 的 Intent。如果 D 具有默认的 "standard" 启动模式,则会启动该类的新实例,且堆栈会变成 A-B-C-D-D。但是,如果 D 的启动模式是 "singleTop",则 D 的现有实例会通过 onNewIntent() 接收 Intent,因为它位于堆栈的顶部;而堆栈仍为 A-B-C-D。但是,如果收到针对 A 类 Activity 的 Intent,则会向堆栈添加 B 的新实例,即便其启动模式为 "singleTop" 也是如此。

注:为某个 Activity 创建新实例时,用户可以按“返回”按钮返回到前一个 Activity。 但是,当 Activity 的现有实例处理新 Intent 时,则在新 Intent 到达 onNewIntent() 之前,用户无法按“返回”按钮返回到 Activity 的状态。

"singleTask"
系统创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的onNewIntent() 方法向其传送 Intent,而不是创建新实例。一次只能存在 Activity 的一个实例。

注:尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。

"singleInstance"
与 "singleTask" 相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。大家可以查看官方文档https://developer.android.com/guide/components/tasks-and-back-stack.html。Activity就介绍到这了。

2.Service

Service也是一个很重要的组件。在Service中可以进行一些耗时操作以及与界面无关的操作。有人可能会问了,耗时操作放在工作线程里不就可以了吗,为什么要使用Service呢?我的理解是这样的:Service进行了很好的封装,除了进行耗时操作以及与界面无关的事情外,还能很好的受控制。例如我们调用context.startService之后,可以方便的调用stopSelf或者stopService。并且可以通过设置Service的粘性决定是否重新启动以及怎样启动这个Service继续工作,而这一点是普通的线程做不到的。当然Service还有另外一种开启方式,即绑定Service。绑定Service相比startService更具有灵活性,而且封装得很好。开启Service和绑定Service是调用不同的生命周期的。





可以看出startService是调用的onCreate() ------>onStartCommand()------>onDestroy(),而bindService调用的是onCreate()------>onBind()------>onUnbind()

startService要执行的onStartCommand()方法的返回值是int类型的,即三种常量

START_STICKY(常量值:1):sticky的意思是“粘性的”。使用这个返回值时,我们启动的服务跟应用程序"粘"在一起,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务。当再次启动服务时,传入的第一个参数将为null;
START_NOT_STICKY(常量值:2):“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT(常量值:3):重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

以上三种情况,可以理解为发生车祸后的人:
START_STICKY:(常量值:1)车祸后自己苏醒,但是失忆;
START_NOT_STICKY:(常量值:2)车祸后再也没有苏醒;
START_REDELIVER_INTENT:(常量值:3)车祸后自己苏醒,依然保持记忆。

除此之外,Service可与AIDL结合实现IPC,这里先不做介绍

3.Broadcast Receiver

 广播接收器。广播接收器可以实现跨Activity的通信。可以自定义Broadcast Receiver来传递数据,也能通过Broadcast Receiver接收系统的广播。当然广播也有不同的形式,如有序广播和无序广播。甚至接收广播后对其拦截,对信息进行修改,然后将数据发送出去。这里不做细致的讨论。具体可参见国内目前最全面的介绍——Android中的BroadCastReceiver文章,写得还是比较全面的。

4.Content Provider

内容提供者。内容提供者可以安全的将私有数据库中的数据有选择性暴露给外界,方便外界的访问。通过设置特定的Uri来向外界提供访问数据的入口。具体是设置匹配规则,然后进行匹配。自定义内容提供者,需要实现创建,获得类型及增删改查等六个方法。通过获得系统的内容提供者,则可以通过query获得系统数据库中的数据。Android API中是这样描述的:

内容提供程序管理对结构化数据集的访问。它们封装数据,并提供用于定义数据安全性的机制。 内容提供程序是连接一个进程中的数据与另一个进程中运行的代码的标准界面。

如果您想要访问内容提供程序中的数据,可以将应用的 Context 中的 ContentResolver 对象用作客户端来与提供程序通信。 ContentResolver 对象会与提供程序对象(即实现 ContentProvider 的类实例)通信。 提供程序对象从客户端接收数据请求,执行请求的操作并返回结果。

如果您不打算与其他应用共享数据,则无需开发自己的提供程序。 不过,您需要通过自己的提供程序在您自己的应用中提供自定义搜索建议。 如果您想将复杂的数据或文件从您的应用复制并粘贴到其他应用中,也需要创建您自己的提供程序。

Android 本身包括的内容提供程序可管理音频、视频、图像和个人联系信息等数据。 android.provider 软件包参考文档中列出了部分提供程序。 任何 Android 应用都可以访问这些提供程序,但会受到某些限制。

具体Content Provider的用法可以参见API文档之Content Provider

以上简单地聊完了四大组件,当然这些组件的应用只是皮毛。但是也需要多使用,并且不断总结,才能收获不一样的东西。

二、不断磨练,不断学习

任何的学习的过程都是要付出一定代价的,Android的知识比较多,而且每个模块也是比较深刻的。对于初学者来说,最忌讳的是急躁。我刚学习Android时就是比较急躁的,总想着很快把学完,但是后来发现这是很困难的。要想弄清楚怎么回事,必须静下心来,慢慢琢磨。只有真正懂了,才知道怎样去造轮子,只有会造轮子了,你的车才能很好的跑起来。

好了,今天就写到这里了,在Android方面我还要学习很多,希望一点一点进步微笑微笑微笑




0 0
原创粉丝点击