android 滤镜 sdk保存

保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
单击提交则表示您同意developerWorks
的条款和条件。 .
所有提交的信息确保安全。
developerWorks 社区:
我的概要信息
选择语言:
本文详细介绍了 Android 应用编程中 Activity 的生命周期、通信方式和 Intent Filter 等内容,并提供了一些日常开发中经常用到的关于 Activity 的技巧和方法。通过本文,你可以进一步了接 Android 中 Activity 的运作方式。
, Android 软件工程师, 重庆索伦互联网信息服务有限公司
张勇,Android 软件工程师,工学学士。现供职于某互联网公司,致力于基于 Android 平台的应用软件开发。
详解 Android 的 Activity 组件Activity 的生命周期和 J2ME 的 MIDlet 一样,在 android 中,Activity 的生命周期交给系统统一管理。与 MIDlet 不同的是安装在 android 中的所有的 Activity 都是平等的。Activity 的状态及状态间的转换在 android 中,Activity 拥有四种基本状态:Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。Paused 当 Activity 被另一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。Stoped 当 Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于 Stoped状态。Killed
Activity 被系统杀死回收或者没有被启动时处于 Killed状态。当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作。下图说明了 Activity 在不同状态间转换的时机和条件:图 1. Activity 的状态转换如上所示,Android 程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就时说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity。当你调用 Activity.finish()方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用 Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active 状态转换 Stoped 状态,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据通过 data参数返回给 Activity1。Activity 栈Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:图 2. Activity 的状态与它在栈中的位置关系如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。Activity 生命周期在 android.app.Activity类中,Android 定义了一系列与生命周期相关的方法,在我们自己的 Activity 中,只是根据需要复写需要的方法,Java 的多态性会保证我们自己的方法被虚拟机调用,这一点与 J2ME 中的 MIDlet 类似。 public class OurActivity extends Activity {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
}这些方法的说明如下:protected void onCreate(Bundle savedInstanceState)一个 Activity 的实例被启动时调用的第一个方法。一般情况下,我们都覆盖该方法作为应用程序的一个入口点,在这里做一些初始化数据、设置用户界面等工作。大多数情况下,我们都要在这里从 xml 中加载设计好的用户界面。例如: setContentView(R.layout.main);当然,也可从 savedInstanceState中读我们保存到存储设备中的数据,但是需要判断 savedInstanceState是否为 null,因为 Activity 第一次启动时并没有数据被存贮在设备中: if(savedInstanceState!=null){
savedInstanceState.get("Key");
}protected void onStart()该方法在 onCreate() 方法之后被调用,或者在 Activity 从 Stop 状态转换为 Active 状态时被调用。protected void onResume()在 Activity 从 Pause 状态转换到 Active 状态时被调用。protected void onResume()在 Activity 从 Active 状态转换到 Pause 状态时被调用。protected void onStop()在 Activity 从 Active 状态转换到 Stop 状态时被调用。一般我们在这里保存 Activity 的状态信息。protected void onDestroy()在 Active 被结束时调用,它是被结束时调用的最后一个方法,在这里一般做些释放资源,清理内存等工作。图 3. 这些方法的调用时机此外,Android 还定义了一些不常用的与生命周期相关的方法可用: protected void onPostCreate(Bundle savedInstanceState);
protected void onRestart();
protected void onPostResume();Android 提供的文档详细的说明了它们的调用规则。创建一个 Activity在 android 中创建一个 Activity 是很简单的事情,编写一个继承自 android.app.Activity的 Java 类并在 AndroidManifest.xml声明即可。下面是一个为了研究 Activity 生命周期的一个 Activity 实例(工程源码见下载):Activity 文件: public class EX01 extends Activity {
private static final String LOG_TAG = EX01.class.getSimpleName();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.e(LOG_TAG, "onCreate");
protected void onStart() {
Log.e(LOG_TAG, "onStart");
super.onStart();
protected void onResume() {
Log.e(LOG_TAG, "onResume");
super.onResume();
protected void onPause() {
Log.e(LOG_TAG, "onPause");
super.onPause();
protected void onStop() {
Log.e(LOG_TAG, "onStop");
super.onStop();
protected void onDestroy() {
Log.e(LOG_TAG, "onDestroy ");
super.onDestroy();
}AndroidManifest.xml 中通过 &activity& 节点说明 Activity,将 apk 文件安装后,系统根据这里的说明来查找读取 Activity,本例中的说明如下: &activity android:name=".EX01" android:label="@string/app_name"&
&intent-filter&
&action android:name="android.intent.action.MAIN" /&
&category android:name="android.intent.category.LAUNCHER" /&
&/intent-filter&
&/activity&启动另外一个 ActivityActivity.startActivity()方法可以根据传入的参数启动另外一个 Activity: Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
startActivity(intent);当然,OtherActivity同样需要在 AndroidManifest.xml 中定义。Activity 之间通信使用 Intent 通信在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。在上面的实例中通过 Activity. startActivity(intent)启动另外一个 Activity 的时候,我们在 Intent 类的构造器中指定了“收件人地址”。如果我们想要给“收件人”Activity 说点什么的话,那么可以通过下面这封“e-mail”来将我们消息传递出去: Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
// 创建一个带“收件人地址”的 email
Bundle bundle =new Bundle();// 创建 email 内容
bundle.putBoolean("boolean_key", true);// 编写内容
bundle.putString("string_key", "string_value");
intent.putExtra("key", bundle);// 封装 email
startActivity(intent);// 启动新的 Activity那么“收件人”该如何收信呢?在 OtherActivity类的 onCreate()或者其它任何地方使用下面的代码就可以打开这封“e-mail”阅读其中的信息: Intent intent =getIntent();// 收取 email
Bundle bundle =intent.getBundleExtra("key");// 打开 email
bundle.getBoolean("boolean_key");// 读取内容
bundle.getString("string_key");上面我们通过 bundle对象来传递信息,bundle维护了一个 HashMap&String, Object&对象,将我们的数据存贮在这个 HashMap 中来进行传递。但是像上面这样的代码稍显复杂,因为 Intent 内部为我们准备好了一个 bundle,所以我们也可以使用这种更为简便的方法: Intent intent =new Intent(EX06.this,OtherActivity.class);
intent.putExtra("boolean_key", true);
intent.putExtra("string_key", "string_value");
startActivity(intent);接收: Intent intent=getIntent();
intent.getBooleanExtra("boolean_key",false);
intent.getStringExtra("string_key");使用 SharedPreferencesSharedPreferences 使用 xml 格式为 Android 应用提供一种永久的数据存贮方式。对于一个 Android 应用,它存贮在文件系统的 /data/ data/your_app_package_name/shared_prefs/目录下,可以被处在同一个应用中的所有 Activity 访问。Android 提供了相关的 API 来处理这些数据而不需要程序员直接操作这些文件或者考虑数据同步问题。 // 写入 SharedPreferences
SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putBoolean("boolean_key", true);
editor.putString("string_key", "string_value");
// 读取 SharedPreferences
SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE);
preferences.getBoolean("boolean_key", false);
preferences.getString("string_key", "default_value");其它方式Android 提供了包括 SharedPreferences 在内的很多种数据存贮方式,比如 SQLite,文件等,程序员可以通过这些 API 实现 Activity 之间的数据交换。如果必要,我们还可以使用 IPC 方式。Activity 的 Intent FilterIntent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为 android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过 &intent-filter &节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。当程序员使用 startActivity(intent) 来启动另外一个 Activity 时,如果直接指定 intent 了对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:图 4. Activity 种 Intent Filter 的匹配过程Action 匹配Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的 Activity 定义时可以在其 &intent-filter &节点指定一个 Action 列表用于标示 Activity 所能接受的“动作”,例如: &intent-filter &
&action android:name="android.intent.action.MAIN" /&
&action android:name="com.zy.myaction" /&
&/intent-filter&如果我们在启动一个 Activity 时使用这样的 Intent 对象: Intent intent =new Intent();
intent.setAction("com.zy.myaction");那么所有的 Action 列表中包含了“com.zy.myaction”的 Activity 都将会匹配成功。Android 预定义了一系列的 Action 分别表示特定的系统动作。这些 Action 通过常量的方式定义在 android.content. Intent中,以“ACTION_”开头。我们可以在 Android 提供的文档中找到它们的详细说明。URI 数据匹配一个 Intent 可以通过 URI 携带外部数据给目标组件。在 &intent-filter &节点中,通过 &data/&节点匹配外部数据。mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定数据的位置、端口、和路径。如下: &data android:mimeType="mimeType" android:scheme="scheme"
android:host="host" android:port="port" android:path="path"/&如果在 Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时 URI 数据匹配才会成功。Category 类别匹配&intent-filter &节点中可以为组件定义一个 Category 类别列表,当 Intent 中包含这个列表的所有项目时 Category 类别匹配才会成功。一些关于 Activity 的技巧锁定 Activity 运行时的屏幕方向Android 内置了方向感应器的支持。在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换。但是有时我们的应用程序仅能在横屏 / 竖屏时运行,比如某些游戏,此时我们需要锁定该 Activity 运行时的屏幕方向,&activity &节点的 android:screenOrientation属性可以完成该项任务,示例代码如下: &activity android:name=".EX01"
android:label="@string/app_name"
android:screenOrientation="portrait"&// 竖屏 , 值为 landscape 时为横屏
&/activity&全屏的 Activity要使一个 Activity 全屏运行,可以在其 onCreate()方法中添加如下代码实现: // 设置全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);在 Activity 的 Title 中加入进度条为了更友好的用户体验,在处理一些需要花费较长时间的任务时可以使用一个进度条来提示用户“不要着急,我们正在努力的完成你交给的任务”。如下图:在 Activity 的标题栏中显示进度条不失为一个好办法,下面是实现代码: // 不明确进度条
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.main);
setProgressBarIndeterminateVisibility(true);
// 明确进度条
requestWindowFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.main);
setProgress(5000);
下载描述名字大小样例代码21KB
参考资料 Google Android 的开发者网站:。中国移动 OPhone 网站关于 OPhne 的文章:。 访问 developerWorks
获得丰富的 how-to 信息、工具和项目更新以及 ,帮助您用开放源码技术进行开发,并将它们与 IBM 产品结合使用。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
IBM PureSystems(TM) 系列解决方案是一个专家集成系统
通过学习路线图系统掌握软件开发技能
软件下载、试用版及云计算
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Open source, LinuxArticleID=463755ArticleTitle=详解 Android 的 Activity 组件publish-date=您所在的位置: &
HTML 5 Canvas滤镜预研(2)
HTML 5 Canvas滤镜预研(2)
HTML5研究小组
HTML 5的canvas相信大家早有听闻,不支持flash的iOS设备要对图形处理可以用它来实现。canvas API内容挺多的,以下只是抽取部分属性和方法来阐述,抛砖引玉一下。
第二. 什么是canvas的像素级处理呢?
大家可以先看抽离出来的:
1. 图像的像素点是怎么存储的?
在进行图像处理前,得先了解一下图像是怎么存储每一个像素点的数据的。
看个图先:
玩css3的同学知道一个新的颜色定义方式&rgba,这里说的跟这个很像。
简单的像素点存储其实把每个像素点用四个数字来存储,分别是R(红)、G(绿)、B(蓝)、A(不透明度),然后这里的A值跟不透明度存在一个关系,60%=153/255,即不透明度=A值/255。
通过改变每个像素点的这四个维度,我们可以达到改变纯度,透明度,色相,亮度等所有效果,这是滤镜的基础原理,玩ps的盆友也许更熟悉这块。
2. Canvas怎么读写所有像素点数据?
a)&&&& 读取
画布的方法:getImageData可以获取指定范围内的像素点数据。参数x、y为起始位置,w、h为范围宽高。
该方法将返回形如以下的对象:
上图对应的是存储两个像素点数据的对象,对象中含有一个叫data的数组,其每四个键值对,存储一个像素点的数据,像素点从左到右排列。
b)&&&& 写入
画布的方法:putImageData可以把指定像素点数据对象(getImageData返回的对象),填充到指定位置,x、y为开始填充点。
第三. 用法?
了解上述原理和方法之后,只要遍历取出的像素点对象,再按指定的算法来改变每个像素点的数据,再把对象重绘到画布。
然后canvas对象来输出编码(第一点),就能达到滤镜效果了。
效果的好坏主要取决于算法的好坏。
需要提醒的是,canvas的像素级处理比较耗费资源,但是对于宽高不是太大的图片,速度还是可以接受的。
这里顺带介绍一下QST库里头关于这个滤镜效果插件的简单使用:
其中preloaded为预载效果数量(由于对于某个图片,效果被渲染后会自动缓存在js对象里头,而执行渲染时需要时间,所以需要预载部分效果)。其他更详细参数,有兴趣的同学可线下交流。
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
内容导航&第 1 页: &第 2 页:
关于的更多文章
本书的重点是使用HTML5、CSS3 及JavaScript 等Web 标准来为iOS
本次的专刊为大家提供了Oracle最新推出的Java SE 8详细的开发教程,从解读到探究Java 8最新
掌握一门技术,首要的是掌握其基础。笔者从事.NET相关
再过十几天很多同学又要爬楼梯睡觉,早上七点起床,晚
8月第二周,开发者们每月必看的编程语言排行榜如期而
本书是在“思想方法学”这一软件工程尚未涉足过的领域中的实习之作。作者亲历国内软件工程的英雄时代、泡沫时代,从失败中醒觉而
51CTO旗下网站android问题收集一
1、什么是 ANR 如何避免它?
ANR 定义 在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户
显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not
Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应
用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性能的设 计很重要,这样,系统不会显示 ANR 给用户。
如何来避免: 考虑上面的 ANR 定义,让我们来研究一下为什么它会在 Android 应用程序里发生和 如何最佳构建应用程序来避免
ANR。 Android 应用程序通常是运行在一个单独的线程(例如,main)里。这意味着你
的应用程序所做的事情如果在主线程里占用了太长的时间的话,就会引发 ANR 对 话框,因为你的应用程序并没有给自己机会来处理输入事件或者
Intent 广播。 因此,运行在主线程里的任何方法都尽可能少做事情。特别是,Activity 应该在 它的关键生命周期方法(如
onCreate()和 onResume())里尽可能少的去做创建操
作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺
寸,应该在子线程里(或者以数据库操作为例,通过异步请求的方式)来完成。 然而,不是说你的主线程阻塞在那里等待子线程的完成——也不是调用
Thread.wait()或是 Thread.sleep()。替代的方法是,主线程应该为子线程提供 一个
Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序, 将能保证你的主线程保持对输入的响应性并能避免由于 5
秒输入事件的超时引发 的 ANR 对话框。这种做法应该在其它显示 UI 的线程里效仿,因为它们都受相同的 超时影响。
IntentReceiver 执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的 工作如保存设定或者注册一个
Notification。和在主线程里调用的其它方法一样 ,应用程序应该避免在 BroadcastReceiver
里做耗时的操作或计算。但不再是在 子线程里做这些任务(因为 BroadcastReceiver 的生命周期短) ,替代的是,如 果响应
Intent 广播需要执行一个耗时的动作的话,应用程序应该启动一个 Service。顺便提及一句,你也应该避免在 Intent
Receiver 里启动一个 Activity ,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果
你的应用程序在响应 Intent 广播时需要向用户展示什么,你应该使用 Notification Manager 来实现。
一般来说,在应用程序里,100 到 200ms 是用户能感知阻滞的时间阈值。因此,这 里有一些额外的技巧来避免
ANR,并有助于让你的应用程序看起来有响应性。 如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度
(ProgressBar 和 ProgressDialog 对这种情况来说很有用) 。 特别是游戏,在子线程里做移动的计算。
如果你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个 Splash Screen
或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该 显示正在进行的进度,以免用户认为应用程序被冻结了。
2、简要解释一下 activity、 intent 、intent
filter、service、Broadcast、
BroadcaseReceiver&&&&&Activity
是所有程序的根本,所有程序的流程都运行在Activity之中,Activity具有自己的生命周期(由系统控制生命周期,程序无法改变,但可以用onSaveInstanceState
保存其状态)。对于Activity,关键是其生命周期的把握,其次就是状态的保存和恢复(onSaveInstanceState
onRestoreInstanceState),以及Activity 之间的跳转和数据传输intent。
&&& Activity
中常用的函数有 SetContentView() findViewById() finish()
startActivity(),其生命周期涉及的函数有:void onCreate(Bundle
savedInstanceState)、void onStart()、void onRestart()、void
onResume()、void onPause()、void onStop()、void
onDestroy()。注意的是,Activity的使用需要在AndroidManifest.xml文件中添加相应的&Activity&,并设置其属性和intent-filter。
Intent:Android中提供了Intent
机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent
的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service
之间的交互。因此,Intent
在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。在SDK中给出了Intent作用的表现形式为:1、通过
Context.startActivity()或者Activity.startActivityForResult()启
动一个Activity;2、通过 Context.startService()
启动一个服务,或者通过Context.bindService()和后台服务交互;3、通过广播方法(如Context.sendBroadcast
(),Context.sendOrderedBroadcast(),Context.sendStickyBroadcast()) 发
给broadcast receivers。Intent 属性的设置,包括以下几点:
(以下为XML中定义,当然也可以通过Intent类的方法来获取和设置)
(1)Action,也就是要执行的动作SDK中定义了一些标准的动作,当然,也可以自定义动作(自定义的动作在使用时,需要加上包名作为前缀,如
"com.example.project.SHOW_COLOR”,并可定义相应的Activity来处理)的自定义动作。(2)Data,也就是执行动作要操作的数据Android中采用指向数据的一个URI来表示,如在联系人应用中,一个指向某联系人的URI可能为:content://contacts/1。对于不同的动作,其URI数据的类型是不同的(可以设置type属性指定特定类型数据),如ACTION_EDIT指定Data为文件URI,打电话为tel:URI,访问网络为
http:URI,而由content provider提供的 数据则为content: URIs。(3)ype(数据类型) ,显式指定
Intent 的数据类型(MIME) 。一般 Intent 的 数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显
式指定的类型而不再进行推导。 (4)category(类别) ,被执行动作的附加信息。例如 LAUNCHER_CATEGORY 表 示
Intent 的接受者应该在 Launcher 中作为顶级应用出现;而 ALTERNATIVE_CATEGORY 表示当前的
Intent 是一系列的可选动作中的一个,这些动 作可以在同一块数据上执行。还有其他的为 Constant Meaning
CATEGORY_BROWSABLE The target activity can be safely invoked by the
browser to display data referenced by a link — for example, an
image or an e-mail message. CATEGORY_GADGET The activity can be
embedded inside of another activity that hosts gadgets.
CATEGORY_HOME The activity displays the home screen, the first
screen the user sees when the device is turned on or when the HOME
key is pressed. CATEGORY_LAUNCHER The activity can be the initial
activity of a task and is listed in the top-level application
launcher. CATEGORY_PREFERENCE The target activity is a preference
panel. (5)component(组件) ,指定 Intent 的的目标组件的类名称。通常 Android 会 根据
Intent 中包含的其它属性的信息,比如 action、data/type、category 进行
查找,最终找到一个与之匹配的目标组件。但是,如果 component 这个属性有指
定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性 以后,Intent 的其它所有属性都是可选的。
(6)extras(附加信息) ,是其它所有附加信息的集合。使用 extras 可以为组
件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮 件的标题、正文等保存在 extras
里,传给电子邮件发送组件。 理解 Intent 的关键之一是理解清楚 Intent 的两种基本用法:一种是显式的 Intent
,即在构造 Intent 对象时就指定接收者;另一种是隐式的 Intent,即 Intent 的发 送者在构造 Intent
对象时,并不知道也不关心接收者是谁,有利于降低发送者和 接收者之间的耦合。 对于显式 Intent,Android
不需要去做解析,因为目标组件已经很明确,Android 需要解析的是那些隐式 Intent,通过解析,将 Intent
映射给可以处理此 Intent 的 Activity、IntentReceiver 或 Service。 Intent
解析机制主要是通过查找已注册在 AndroidManifest.xml 中的所有 IntentFilter 及其中定义的
Intent,最终找到匹配的 Intent。在这个解析过程中 ,Android 是通过 Intent 的
action、type、category 这三个属性来进行判断的, 判断方法如下: · 如果 Intent 指明定了
action,则目标组件的 IntentFilter 的 action 列表中就 必须包含有这个 action,否则不能匹配; ·
如果 Intent 没有提供 type,系统将从 data 中得到数据类型。和 action 一样, 目标组件的数据类型列表中必须包含
Intent 的数据类型,否则不能匹配。 · 如果 Intent 中的数据不是 content: 类型的 URI,而且 Intent
也没有明确指定 它的 type,将根据 Intent 中数据的 scheme (比如 http: 或者 mailto:) 进行匹
配。同上,Intent 的 scheme 必须出现在目标组件的 scheme 列表中。 · 如果 Intent 指定了一个或多个
category,这些类别必须全部出现在组建的类 别列表中。比如 Intent 中包含了两个类别:LAUNCHER_CATEGORY
和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。 Intent-Filter 的定义
一些属性设置的例子: &action
android:name="com.example.project.SHOW_CURRENT" /&
android:name="android.intent.category.DEFAULT" /&
&data android:mimeType="video/mpeg"
android:scheme="http" . . . /& &data
android:mimeType="image/*" /& &data
android:scheme="http" android:type="video/*" /&
完整的实例 &activity android:name="NotesList"
android:label="@string/title_notes_list"&
&intent-filter&
android:name="android.intent.action.MAIN"/&
android:name="android.intent.category.LAUNCHER"/&
&/intent-filter&
&intent-filter&
android:name="android.intent.action.VIEW"/&
android:name="android.intent.action.EDIT"/&
android:name="android.intent.action.PICK"/&
android:name="android.intent.category.DEFAULT"/&
android:mimeType="vnd.android.cursor.dir/vnd.google.note"/&
&/intent-filter&
&intent-filter&
android:name="android.intent.action.GET_CONTENT"/&
android:name="android.intent.category.DEFAULT"/&
android:mimeType="vnd.android.cursor.item/vnd.google.note"/&
&/intent-filter&
&/activity& Intent 用法实例 1.无参数
Activity 跳转 Intent it = new Intent(Activity.Main.this,
Activity2.class); startActivity(it); 2.向下一个 Activity 传递数据(使用 Bundle
和 Intent.putExtras) Intent it = new Intent(Activity.Main.this,
Activity2.class); Bundle bundle=new Bundle();
bundle.putString("name", "This is from MainActivity!");
it.putExtras(bundle); // it.putExtra(“test”, "shuju”);
startActivity(it); // startActivityForResult (it,REQUEST_CODE);
对于数据的获取可以采用: Bundle bundle=getIntent().getExtras();String
name=bundle.getString("name"); 3.向上一个 Activity 返回结果(使用 setResult,针对
startActivityForResult (it,REQUEST_CODE)启动的 Activity) Intent
intent=getIntent(); Bundle bundle2=new Bundle();
bundle2.putString("name", "This is from ShowMsg!");
intent.putExtras(bundle2); setResult(RESULT_OK, intent); 4.回调上一个
Activity 的结果处理函数(onActivityResult) @Override protected void
onActivityResult(int requestCode, int resultCode, Intent data) { //
TODO Auto-generated method stub super.onActivityResult(requestCode,
resultCode, data); if (requestCode==REQUEST_CODE){
if(resultCode==RESULT_CANCELED) setTitle("cancle"); else if
(resultCode==RESULT_OK) { String temp= Bundle
bundle=data.getExtras(); if(bundle!=null)
temp=bundle.getString("name"); setTitle(temp); } } } 下面是转载来的其他的一些
Intent 用法实例(转自 javaeye) 显示网页 1. Uri uri = Uri.parse(""); 2. Intent it = new
Intent(Intent.ACTION_VIEW, uri); 3. startActivity(it); 显示地图 1. Uri
uri = Uri.parse("geo:38..036476"); 2. Intent it = new
Intent(Intent.ACTION_VIEW, uri); 3. startActivity(it); 4. //其他 geo
URI 范例 5. //geo:latitude,longitude 6.
//geo:latitude,longitude?z=zoom 7. //geo:0,0?q=my+street+address 8.
//geo:0,0?q=business+near+city 9.
//google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom
路径规划 1. Uri uri = Uri.parse("?
f=d&saddr=startLat
startLng&daddr=endLat
endLng&hl=en"); 2. Intent it = new
Intent(Intent.ACTION_VIEW, uri); 3. startActivity(it); 4. //where
startLat, startLng, endLat, endLng are a long with 6 decimals like:
50.123456 打电话 1. //叫出拨号程序 2. Uri uri = Uri.parse("tel:");
3. Intent it = new Intent(Intent.ACTION_DIAL, uri); 4.
startActivity(it); 1. //直接打电话出去 2. Uri uri =
Uri.parse("tel:"); 3. Intent it = new
Intent(Intent.ACTION_CALL, uri); 4. startActivity(it); 5. //用这个,要在
AndroidManifest.xml 中,加上 6. //&uses-permission
id="android.permission.CALL_PHONE" /& 传送 SMS/MMS 1.
//调用短信程序 2. Intent it = new Intent(Intent.ACTION_VIEW, uri); 3.
it.putExtra("sms_body", "The SMS text"); 4.
it.setType("vnd.android-dir/mms-sms"); 5. startActivity(it); 1.
//传送消息 2. Uri uri = Uri.parse("smsto://"); 3. Intent it =
new Intent(Intent.ACTION_SENDTO, uri); 4. it.putExtra("sms_body",
"The SMS text"); 5. startActivity(it); 1. //传送 MMS 2. Uri uri =
Uri.parse("content://media/external/images/media/23"); 3. Intent it
= new Intent(Intent.ACTION_SEND); 4. it.putExtra("sms_body", "some
text"); 5. it.putExtra(Intent.EXTRA_STREAM, uri); 6.
it.setType("image/png"); 7. startActivity(it); 传送 Email 1. Uri uri
= Uri.parse("");
2. Intent it = new Intent(Intent.ACTION_SENDTO, uri); 3.
startActivity(it); 1. Intent it = new Intent(Intent.ACTION_SEND);
2. it.putExtra(Intent.EXTRA_EMAIL, ""); 3.
it.putExtra(Intent.EXTRA_TEXT, "The email body text"); 4.
it.setType("text/plain"); 5. startActivity(Intent.createChooser(it,
"Choose Email Client")); 1. Intent it=new
Intent(Intent.ACTION_SEND); 2. String[] tos={""}; 3. String[] ccs={""}; 4.
it.putExtra(Intent.EXTRA_EMAIL, tos); 5.
it.putExtra(Intent.EXTRA_CC, ccs); 6.
it.putExtra(Intent.EXTRA_TEXT, "The email body text"); 7.
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 8.
it.setType("message/rfc822"); 9.
startActivity(Intent.createChooser(it, "Choose Email Client")); 1.
//传送附件 2. Intent it = new Intent(Intent.ACTION_SEND); 3.
it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 4.
it.putExtra(Intent.EXTRA_STREAM, ""); 5.
sendIntent.setType("audio/mp3"); 6.
startActivity(Intent.createChooser(it, "Choose Email Client"));
播放多媒体 Uri uri = Uri.parse(""); Intent it
= new Intent(Intent.ACTION_VIEW, uri); it.setType("audio/mp3");
startActivity(it); Uri uri = Uri.withAppendedPath
(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); Intent it = new
Intent(Intent.ACTION_VIEW, uri); startActivity(it); Market 相关 1.
//寻找某个应用 2. Uri uri =
Uri.parse("market://search?q=pname:pkg_name"); 3. Intent it = new
Intent(Intent.ACTION_VIEW, uri); 4. startActivity(it); 5. //where
pkg_name is the full package path for an application 1.
//显示某个应用的相关信息 2. Uri uri = Uri.parse("market://details?id=app_id");
3. Intent it = new Intent(Intent.ACTION_VIEW, uri); 4.
startActivity(it); 5. //where app_id is the application ID, find
the ID 6. //by clicking on your application on Market home 7.
//page, and notice the ID from the address bar Uninstall 应用程序 1.
Uri uri = Uri.fromParts("package", strPackageName, null); 2. Intent
it = new Intent(Intent.ACTION_DELETE, uri); 3. startActivity(it);
service service 是没有界面的长生命周期的代码。一个很好的例子是媒体播放器从列表
中播放歌曲。在一个媒体播放器程序中,大概要有一个或多个活动(activity)
来供用户选择歌曲并播放它。然而,音乐的回放就不能使用活动(activity)了
,因为用户希望他导航到其他界面时音乐继续播放。这种情况下,媒体播放器活 动(activity)要用
Context.startService()启动一个服务来在后台运行保持音
乐的播放。系统将保持这个音乐回放服务的运行直到它结束。注意一下,你要用
Context.bindService()方法连接服务(如果它没有运行,要先启动它) 。当连
接到服务后,你可以通过服务暴露的一个接口和它通信。对于音乐服务,它允许 你暂停、倒带,等等。 Broadcast 和
BroadcaseReceiver Android BroadcastReceiver 简介 在 Android 中使用
Activity, Service, Broadcast, BroadcastReceiver 活动(Activity) -
用于表现功能 服务(Service) - 相当于后台运行的 Activity 广播(Broadcast) - 用于发送广播
广播接收器(BroadcastReceiver) - 用于接收广播 Intent - 用于连接以上各个组件,并在其间传递消息
BroadcastReceiver 在 Android 中,Broadcast 是一种广泛运用的在应用程序之间传输信息的机制 。而
BroadcastReceiver 是对发送出来的 Broadcast 进行过滤接受并响应的一类 组件。下面将详细的阐述如何发送
Broadcast 和使用 BroadcastReceiver 过 滤接收的过程:
首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如 Action 、Category)装入一个 Intent
对象,然后通过调用 Context.sendBroadcast()、 sendOrderBroadcast()或
sendStickyBroadcast()方法,把 Intent 对象以广播方 式发送出去。 当 Intent
发送以后,所有已经注册的 BroadcastReceiver 会检查注册时的 IntentFilter 是否与发送的 Intent
相匹配,若 匹配则就会调用 BroadcastReceiver 的 onReceive()方法。所以当我们定义一个
BroadcastReceiver 的时候,都需要 实现 onReceive()方法。 注册 BroadcastReceiver
有两种方式: 一种方式是,静态的在 AndroidManifest.xml
中用&receiver&标签生命注册
,并在标签内用&intent- filter&标签设置过滤器。
另一种方式是,动态的在代码中先定义并设置好一个 IntentFilter 对象, 然后在需要注册的地方调
Context.registerReceiver()方法,如果取消时就调 用
Context.unregisterReceiver()方法。 不管是用 xml
注册的还是用代码注册的,在程序退出的时候没有特殊需要都得注销 ,否则下次启动程序可能会有多个 BroadcastReceiver
另外,若在使用 sendBroadcast()的方法是指定了接收权限,则只有在 AndroidManifest.xml
中用&uses- permission&标签声明了拥有此权限的
BroascastReceiver 才会有可能接收到发送来的 Broadcast。 同样,若在注册 BroadcastReceiver
时指定了可接收的 Broadcast 的权限,则 只有在包内的 AndroidManifest.xml 中
用&uses-permission&标签声明了,拥有 此权限的
Context 对象所发送的 Broadcast 才能被这个 BroadcastReceiver 所接收 。 动态注册:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(String);--为 BroadcastReceiver 指定 action,
使之用于接收同 action 的广播 registerReceiver
(BroadcastReceiver,intentFilter); 一般:在 onStart 中注册,onStop 中取消
unregisterReceiver 发送广播消息:extends Service 指定广播目标 Action:Intent
Intent = new Intent(action-String) --指定了此 action 的 receiver 会接收此广播
需传递参数(可选) putExtra(); 发送:sendBroadcast(Intent);
5、IntentService 有何优点?
IntentService is a base class for Services that handle asynchronous
requests (expressed as Intents) on demand. Clients send requests
through startService(Intent) the service is started as
needed, handles each Intent in turn using a worker thread, and
stops itself when it runs out of work. This ‘work queue processor’
pattern is commonly used to offload tasks from an application’s
main thread. The IntentService class exists to simplify this
pattern and take care of the mechanics. To use it, extend
IntentService and implement onHandleIntent(Intent). IntentService
will receive the Intents, launch a worker thread, and stop the
service as appropriate. All requests are handled on a single worker
thread — they may take as long as necessary (and will not block the
application’s main loop), but only one request will be processed at
a time.” IntentService 的好处 Acitivity 的进程,当处理 Intent 的时候,会产生一个对应的
Service Android 的进程处理器现在会尽可能的不 kill 掉你 非常容易使用 日历中 IntentService 的应用
public class DismissAllAlarmsService extends IntentService {
@Override public void onHandleIntent(Intent unusedIntent) {
ContentResolver resolver = getContentResolver(); ...
resolver.update(uri, values, selection, null); } } in AlertReceiver
extends BroadcastReceiver, onReceive(): (main thread) Intent intent
= new Intent(context, DismissAllAlarmsService.class);
context.startService(intent); 6.根据自己的理解描述下 Android 数字签名 Android
数字签名 在 Android 系统中,所有安装到系统的应用程序都必有一个数字证书,此
数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个 permission 的 protectionLevel 为
signature,那么就只有那些跟该 permission 所 在的程序拥有同一个数字证书的应用程序才能取得该权限。Android
使用 Java 的 数字证书相关的机制来给 apk 加盖数字证书,要理解 android 的数字证书,需要先 了解以下数字证书的概念和
java 的数字证书机制。Android 系统要求每一个安装 进系统的应用程序都是经过数字证书签名的,数字证书的私钥则保存在程序开发
者的手中。Android 将数字证书用来标识应用程序的作者和在应用程序之间建立
信任关系,不是用来决定最终用户可以安装哪些应用程序。这个数字证书并不需
要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。 同一个开发者的多个程序尽可能使用同一个数字证书,这可以带来以下好处。
(1)有利于程序升级,当新版程序和旧版程序的数字证书相同时,Android 系统才
会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证 书不相同,则 Android
系统认为他们是不同的程序,并产生冲突,会要求新程序 更改包名。 (2)有利于程序的模块化设计和开发。Android
系统允许拥有同一个数字签名的程 序运行在一个进程中,Android 程序会将他们视为同一个程序。所以开发者可以
将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。
(3)可以通过权限(permission)的方式在多个程序间共享数据和代码。Android 提
供了基于数字证书的权限赋予机制,应用程序可以和其他的程序共享概功能或者
数据给那那些与自己拥有相同数字证书的程序。如果某个权限(permission)的 protectionLevel 是
signature,则这个权限就只能授予那些跟该权限所在的包拥 有同一个数字证书的程序。 在签名时,需要考虑数字证书的有效期:
(1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改 数字证书的程序将不能正常升级。
(2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序 的预计生命周期。 (3)Android Market
强制要求所有应用程序数字证书的有效期要持续到 2033 年 10 月 22 日以后。 Android 数字证书包含以下几个要点:
(1)所有的应用程序都必须有数字证书,Android 系统不会安装一 个没有数字证书的应用程序 (2)Android
程序包使用的数字证书可以是自签名的,不需要一个 权威的数字证书机构签名认证 (3)如果要正式发布一个 Android
,必须使用一个合适的私钥生 成的数字证书来给程序签名,而不能使用 adt 插件或者 ant 工具生成的调试证书来 发布。
(4)数字证书都是有有效期的,Android 只是在应用程序安装的时
候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影 响程序的正常功能。 Android 面试题 1. 请描述下
Activity 的生命周期。 oncreate() onstart() onresume() onpause() onstop()
onrestart() ondestroy()
2. 如果后台的 Activity 由于某原因被系统回收了,如何在被系统回收之前保存 当前状态? 重写 onDestroy
方法,在方法中保存
3. 如何将一个 Activity 设置成窗口的样式。
(Edited by Sodino) 可以直接添加您对应需要展示为 Dialog style 的 Activity 的
android:theme 属性 值为
android:theme="@android:style/Theme.Dialog"。
4. 如何退出 Activity?如何安全退出已调用多个 Activity 的 Application?
1、抛异常强制退出: 该方法通过抛异常,使程序 Force Close。 验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出
Force Close 的窗口。
2、记录打开的 Activity: 每打开一个 Activity,就记录下来。在需要退出时,关闭每一个 Activity
3、发送特定广播: 在需要结束应用时,发送一个特定的广播,每个 Activity 收到广播后,关闭即可 。
4、递归退出 在打开新的 Activity 时使用 startActivityForResult,然后自己加标志,在
onActivityResult 中处理,递归关闭。
5. 请介绍下 Android 中常用的五种布局。
线性布局(LinearLayout) 表格布局(TableLayout) 单帧布局(FrameLayout)
最简单的布局格式,他可以防止任何空件,但是都只能罗列到左上角,不能进行 复杂的布局 相对布局(RelativeLayout)
坐标布局(AbsoluteLayout)
6. 请介绍下 Android 的数据存储方式。(Edited by Sodino) Android 提供了 5
种方式存储数据:
--使用 SharedPreferences 存储数据;
--文件存储数据;
--SQLite 数据库存储数据;
--使用 ContentProvider 存储数据;
--网络存储数据(参考 java.net.*和 android.net.*包)
一:使用 SharedPreferences 存储数据 首先说明 SharedPreferences 存储方式,它是 Android
提供的用来存储一些简单配 置信息的一种机制,例如:登录用户的用户名与密码。其采用了 Map 数据结构来
存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下: void ReadSharedPreferences(){
String strName,strP SharedPreferences user =
getSharedPreferences(“user_info”,0); strName =
user.getString(“NAME”,””); strPassword = user
getString(“PASSWORD”,””); } void WriteSharedPreferences(String
strName,String strPassword){ SharedPreferences user =
getSharedPreferences(“user_info”,0); uer.edit();
user.putString(“NAME”, strName); user.putString(“PASSWORD”
,strPassword); mit(); } 数据读取与写入的方法都非常简单,只是在写入的时候有些区别:先调用
edit() 使其处于编辑状态,然后才能修改数据,最后使用 commit()提交修改的数据。实 际上
SharedPreferences 是采用了 XML 格式将数据存储到设备中,在 DDMS 中的 File Explorer
中的/data/data/&package
name&/shares_prefs 下。以上面的数据存储 结果为例,打开后可以看到一个
user_info.xml 的文件,打开后可以看到: &?xml version=”1.0〃
encoding=”UTF-8〃?&
&map& &string
name=”NAME”&moandroid&/string&
&string name=”
PASSWORD”&SharedPreferences&/string&
&/map& 使用 SharedPreferences
是有些限制的:只能在同一个包内使用,不能在不同的 包之间使用。 二:文件存储数据 文件存储方式是一种较常用的方法,在 Android
中读取/写入文件的方法,与 Java 中实现 I/O 的程序是完全一样的,提供了 openFileInput()和
openFileOutput()方 法来读取设备上的文件。FilterInputStream, FilterOutputStream
等可以到 Java io package 说明中去详细学习,不再此详细说明,具体实例如下: String fn =
“moandroid.log”; FileInputStream fis = openFileInput(fn);
FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);
除此之外,Android 还提供了其他函数来操作文件,详细说明请阅读 Android SDK 。 7. 请介绍下
ContentProvider 是如何实现数据共享的。 在 Android 应用程序之间数据共享—-ContentResolver
中,已经说明了 Android 是如何实现应用程序之间数据共享的,并详细解析了如何获取其他应用程序共享
的数据。ContentProviders 存储和检索数据,通过它可以让所有的应用程序访问
到,这也是应用程序之间唯一共享数据的方法。那么如何将应用程序的数据暴露 出去? 通过以前文章的学习,知道
ContentResolver 是通过 ContentProvider 来获取其他 与应用程序共享的数据,那么
ContentResolver 与 ContentProvider 的接口应该差 不多的。 其中 ContentProvider 负责
?组织应用程序的数据; ?向其他应用程序提供数据; ContentResolver 则负责 ?获取 ContentProvider
提供的数据; ?修改/添加/删除更新数据等; ContentProvider 是如何向外界提供数据的? Android 提供了
ContentProvider,一个程序可以通过实现一个 ContentProvider 的抽象接口将自己的数据完全暴露出去,而且
ContentProviders 是以类似数据库 中表的方式将数据暴露,也就是说 ContentProvider 就像一个“数据库”
。那么 外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不 过是采用 URI 来表示外界需要访问的“数据库”
。至于如何从 URI 中识别出外界需 要的是哪个“数据库” ,这就是 Android 底层需要做的事情了,不在此详细说。 简要分析下
ContentProvider 向外界提供数据操作的接口: query(Uri, String[], String,
String[], String) insert(Uri, ContentValues) update(Uri,
ContentValues, String, String[]) delete(Uri, String, String[])
这些操作与数据库的操作基本上完全一样,在此不详细说,具体的解析可以参考 Android Sqlite
解析篇中的详细说明。需要特殊说明的地方是 URI: 在 URI 的 D 部分可能包含一个_ID ,这个应该出现在 SQL
语句中的,可以以种特殊 的方式出现,这就要求我们在提供数据的时候,需要来额外关注这个特殊的信息 。Android SDK
推荐的方法是:在提供数据表字段中包含一个 ID,在创建表时 INTEGER PRIMARY KEY AUTOINCREMENT 标识此
ID 字段。 ContentProvider 是如何组织数据的?
组织数据主要包括:存储数据,读取数据,以数据库的方式暴露数据。数据的存
储需要根据设计的需求,选择合适的存储结构,首选数据库,当然也可以选择本
地其他文件,甚至可以是网络上的数据。数据的读取,以数据库的方式暴露数据 这就要求,无论数据是如何存储的,数据最后必须以数据的方式访问。
可能还有 2 个问题,是需要关注的。 1.ContentProvider 是什么时候创建的,是谁创建的?访问某个应用程序共享的
数据,是否需要启动这个应用程序?这个问题在 Android SDK 中没有明确说明,
但是从数据共享的角度出发,ContentProvider 应该是 Android 在系统启动时就创
建了,否则就谈不上数据共享了。这就要求在 AndroidManifest.XML 中使用
&provider&元素明确定义。 2.可能会有多个程序同时通过
ContentResolver 访问一个 ContentProvider,会不
会导致像数据库那样的“脏数据”?这个问题一方面需要数据库访问的同步,尤 其是数据写入的同步,在 AndroidManifest.XML
中定义 ContentProvider 的时候,
需要考虑是&provider&元素 multiprocess
属性的值;另外一方面 Android 在 ContentResolver 中提供了
notifyChange()接口,在数据改变时会通知其他 ContentObserver,这个地方应该使用了观察者模式,在
ContentResolver 中应 该有一些类似 register,unregister 的接口。 至此,已经对
ContentProvider 提供了比较全面的分析,至于如何创建 ContentProvider,可通过 2
种方法:创建一个属于你自己的 ContentProvider 或 者将你的数据添加到一个已经存在的 ContentProvider
中,当然前提是有相同数 据类型并且有写入 Content provider 的权限。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 android拍照保存 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信