Android应用程序开发疑问
为什么android.util.log会提供五种不同级别的打印输出方式?(打印输出在Logcat窗口)比如:Log.v()用于打印比较琐碎的信息;Log.d()用于打印调试信息;Log.i()用于打印比较重要的数据信息;Log.w()用于打印一些警告信息,提示程序可能存在的潜在风险;Log.e()打印程序中错误信息。-->个人理解:可在应用程序中的任何地方使用以上五种不同的Log输出方式,但是建议“有目的和区分度”地使用,只有这样才能够方便使用其过滤功能,并能够分析程序的执行路径(在不同的路径使用不用的级别输出Log)。
Android应用程序的AndroidManifest.xml文件,在注册activity时,使用的label标签指定活动(Activity)中标题栏内容。标题栏是显示在活动最顶的;此外,给主活动指定的label不仅会成为标题栏中的内容,还会成为启动器Launcher中应用显示的名称。
活动Activity部分,总结:四种状态(针对于Activity存在于任务栈中的状态:运行状态、暂停状态、停止状态和销毁状态)、三种生存期(针对于生命周期而言:完整生存期、可见生存期和前台生存期)和七个回调方法(onCreate() onStart() onResume() onPause() onStop() onDestory() onRestart()),以及四种启动模式(Standard-->SingleTop-->SingleTask-->SingleInstance)。
多个Activity之间传递值时,使用包名作为前缀(确保唯一性),例如: public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
不要BroadcastReceiver的onReceive()中执行过多的逻辑或者进行任何的耗时操作,因为广播接受者中是不允许开启线程的,当onReceive()运行了较长时间而没有结束时,程序就会报错。广播接受者更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。
广播是一种跨进程的通信方式(应用程序能够接受系统广播)。
正是由于广播机制是一种跨进程的通信方式,很有可能会导致程序的不安全性。为了解决广播的安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够字应用程序内部进行传递,并且广播接受者也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。
使用本地广播的几点优势:
1. 明确地知道正在发送的广播不会离开我们的程序,不需要担心机密数据泄露;
2. 其他程序无法将广播发送到我们的程序内部,不需要担心会有安全漏洞的隐患;
3. 发送本地广播比起发送系统全局广播会带来更高效率。
Android系统提供三种方式用于简单地实现数据持久化功能,即:文件存储、SharedPreference存储以及数据库存储。除了这三种方式之外,还可以将数据保存到手机的SD卡上,不过使用前三种方式相对简单,且比起存储到SD卡中会更加安全。
文件存储方式:不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,比较适合用于存储一些简单的文本信息或二进制数据。如果想使用文件存储的方式来保存一些复杂的文本数据,就需要定义一套自己的格式规范,方便以后将数据从文件中重新解析出来。
Context类提供openFileOutput()用于将数据存储到指定的文件中,所有文件默认保存到/data/data/<packagename>/files/目录下。
文件存储方式不适合用于保存一些较为复杂的文本数据。
三种方式得到SharedPreferences实例:
1. Context类中的getSharedPreferences()
方法接收两个参数,前者为SharedPreferences文件名,后者为操作模式。SharedPreferences文件都是存放在/data/data/<packagename>/shared_prefs/目录下的。MODE_PRIVATE模式表示只有当前应用程序才可以对这个文件进行读写操作;MODE_MULTI_PROCESS模式(This constant was deprecated in API level 23.)一般用于会在多个进程中对同一个SharedPreferences文件读写。MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE两种模式:This constant was deprecated in API level 17. 官方已经不再推荐使用这种方式实现进程间的数据共享。而推荐使用更加安全可靠的内容提供器技术。
2. Activity类中的getPreferences()
使用这个方法时,会自动将当前的类名作为SharedPreferences文件名。
3. PreferenceManager类中的getDefaultSharedPreferences()
是一个静态方法,自动使用当前应用程序的包名作为前座来命名SharedPreferences文件。
SharedPreferences文件是使用XML的格式来对数据进行管理的。
SQLite数据库文件会存放到/data/data/<packagename>/databases/目录下。使用数据库存储数据,一般包含两个部分:数据库,以及存储在数据库中的表——table。
如果想要使用adb工具,需要将adb tool所在的路径配置到系统环境变量中;如果需要操作数据库,首先进入到数据库所在的目录,然后输入:sqlite3 database_name。
数据库操作支持事务处理,也就是让事务支持的业务逻辑执行完毕时才产生想要的效过,若中途崩溃,则退回到启动事务的起点。
ContentProvider内容提供者可以选择只对哪一个部分数据进行共享,从而保证隐私数据的安全性。
内容提供者一般有两种使用方式:一是使用现有的内容提供者来读取和操作相应程序的数据;二是创建自己的内容提供者给我们程序中的数据提供外部访问接口。
Service:Android的后台运行功能,也就是说,应用程序即使在关闭的情况下仍然可以再后台继续运行;IOS是不支持后台的,当应用程序不在前台运行时就会进入到挂起状态。服务Service是Android中实现后台运行的解决方案,适合去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖于任何用户界面,即使当程序被切换到后台,或者用户打开了另一个应用程序,服务仍然能保持正常运行。
需要注意的是,服务并不是运行在一个独立地应用程序中的,而是依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
实际上服务并不会自动开启线程,所有代码都是默认运行在主线程中的。也就是说,我们需要在服务内部手动创建子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞的的情况。
Android的UI是线程不安全的。如果想要更新应用程序里的UI元素,则必须在主线程中进行,否则就会出现异常。如果确实需要在子线程执行耗时任务,然后根据任务的执行结果来更新相应的UI控件,该如何处理?
Android中的异步和同步机制:Synchronous同步和Asynchronous异步的概念最初来自通信领域。通信同步指客户端在发出请求后,必须要在服务端有回应后客户端才继续发送其他请求,所有的请求都会在服务端得到同步,直到服务端发返回请求;通信异步指客户端在发送请求后,不必等待服务端的回应就可以发送下一个请求,对所有的请求动作来说将会在服务端得到异步,这条请求的链路就像是一个请求队列,所有的请求动作在这里都不会得到同步。
异步消息处理机制解决子线程中进行UI操作的问题。Android中的异步消息处理主要有四个部分组成,Message(用于在不同线程之间交换数据,是在线程之间传递的消息)、Handler(主要用于发送和处理消息的)、MessageQueue(用于存放所有通过Handler发送的消息,每个线程都会有一个MessageQueue)和Looper(是每个线程中的MessageQueue的管家,每个线程只会有一个Looper对象)。
另一个工具:AsyncTask,背后的实现原理也是基于异步消息处理机制,只是Android进行了封装。
停止Service的方式:在Activity中决定服务何时启动和停止,startService()和stopService()用于服务的启动和停止。此外,在服务中调用自己的stopSelf()可以实现服务的停止。
活动和服务的通信:在活动中指挥服务去干什么,服务就去干什么;通过bindService()实现活动和服务的交互。
服务中的代码默认运行在主线程中,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR。因此,需要在服务中创建子线程,然后在这里去处理那些耗时的逻辑。一般是在onStartCommand()中创建并开启子线程,并在其中调用stopSelf()停止服务。
Android专门提供了IntentService(),用于解决上述的两个步骤。复写onHandleIntent(),并在其中执行耗时操作,因为这个方法中的内容会在子线程中执行,而不必担心ANR的问题。在执行完上述方法后,会自动结束去执行onDestory()。上述IntentService实例集开启线程和自动停止于一身。
实践P376 中的定时任务。
使用Intent实例传递自定义对象,必要条件:自定义类必须实现Serializable或者Parcelable接口。不同之处在于:前者是将对象进行序列化,后者则将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型。虽然后者在实现上会显得复杂,但效率会更好,所以推荐使用后者。
编写测试用例,创建测试工程,进行单元测试,实践P468的单元测试功能。
Android应用程序开发疑问的更多相关文章
- 【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)
最近一直在看的一本书是<Android 应用程序开发权威指南>(第四版),十分推荐.书中讲到了一些用户界面设计的规范,对于初学者我认为十分有必要,在这里码给大家,希望对我们都有用. 在我们 ...
- Android应用程序开发之图片操作(一)——Bitmap,surfaceview,imageview,Canvas
Android应用程序开发之图片操作(一)——Bitmap,surfaceview,imageview,Canvas 1,Bitmap对象的获取 首先说一下Bitmap,Bitmap是Androi ...
- 关于怎么快速学好Android应用程序开发及其其他编程语言(大牛和高手勿喷,此篇文章也适合刚入门小师弟和小师妹)
无论你是从.NET转过来的也好 还是从PHP转过来的等等等,能看到这篇文章的人一般都是想快速转行到Android应用程序开发,希望我的这篇文章能勉励到各位的同时,也能勉励我自己. 1.编程语言基本都会 ...
- Kotlin 编程语言成为其 Android 应用程序开发人员的首选语言
今年 5 月,谷歌在 I/O 大会上宣布,Kotlin 编程语言成为其 Android 应用程序开发人员的首选语言. Kotlin 是一种面向现代多平台应用程序的编程语言,成为谷歌开发 Android ...
- Android应用程序开发之图片操作(二)——工程图片资源的加载及OOM的处理
(一)工程图片资源的加载方法 在Android应用程序开发之图片操作(一)中,详细说明了如何操作各种资源图片,只是有的没有附上示例代码,在此,我将针对项目工程中的图片资源的显示加载进行说明.官方说明, ...
- 【Android 应用程序开发】 Fragment 详细说明
笔者 : 汉书亮 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38064191 本博客代码地址 : -- 单一 Fragmen ...
- Android应用程序开发中碰到的错误和获得的小经验
1,Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE Description:这表示手机内存不足,对内存较小的手机经常会出现这样的问题,从 ...
- 2.3搭建Android应用程序开发环境
1.安装Android SDK (1)首选下载Android SDK: (2)下载完成之后,在Ubuntu系统下进行解压: (3)解压完成之后,配置环境变量: ①用vim打开/etc/profile文 ...
- Android应用程序开发
第一章 Android应用初体验 1.1应用基础 activity是Android SDK中Activity类的一个具体实例,负责管理用户与信息屏的交互. 应用的功能是通过编写一个个Activity子 ...
随机推荐
- pycharm提示This inspection detects any methods which may safely be made static.
示例代码: class Car(object): # 未定义任何类属性 def move(self): # 方法会出现下划线提示This inspection detects any methods ...
- loadrunner出现报错operands of = have illegal types `pointer to char' and `int'
原始代码: void split(char * p,char * str){ /* 传入一个数组进行p和一个以什么进行分割的str,返回切片后的值 */ int i = 0, j = 0; char ...
- shell 判断目录是否存在
判断/data/www/logs/wos_log/crontab_log是否, 如果不存在则新建 if [ ! -d "/data/www/logs/wos_log/crontab_log& ...
- HDU 4763 Theme Section(KMP灵活应用)
Theme Section Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 关于yum网络版仓库(本地yum仓库的安装配置,如果没网了,做一个局域网内的yum仓库)
2017-11-13 22:49:48 1:两种方式: a.每一台机器都配一个本地文件系统上的yum仓库 file:///packege/path/ b.在局域网内部配置一台节点(server-b ...
- java的局部变量和成员变量以及区别
一.局部变量 存在某个方法中的变量就叫局部变量,局部变量一旦声明就必须赋值 否则不能使用 代码如下: class Person { String name; char sex; int age; pu ...
- Tychonov Theorem
(Remark: The proof presented in this post is a reorganization and interpretation of that given by Ja ...
- Asp.Net Mvc 返回类型总结
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- ng2tree在ios中无法触发click
问题描述: 从其他页面跳转回ng2tree的页面时,无法触发节点的click事件 解决方案: 1. 在node_modules中搜索onNodeSeclected方法,修改click为touchend ...
- nginx与php-fpm通信的两种方式
简述 在linux中,nginx服务器和php-fpm可以通过tcp socket和unix socket两种方式实现. unix socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数 ...