初学Android开发,如何在threadcontext中传入context

总数:26674,共534页
最后更新时间
最后更新时间
总数:26674,共534页Java(53)
&&&&&&& 大家好,& 今天给大家介绍下我们在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中
&& 时刻的在与它打交道,例如:Service、BroadcastReceiver、Activity等都会利用到Context的相关方法 ; 说它陌生,完全是
&& 因为我们真正的不懂Context的原理、类结构关系。一个简单的问题是,一个应用程序App中存在多少个Context实例对象呢?
&& 一个、两个? 在此先卖个关子吧。读了本文,相信您会豁然开朗的 。
&&&&& Context,中文直译为“上下文”,SDK中对其说明如下:
&& Interface to global information about an application environment. This is an abstract class whose implementation
& is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls&
& for application-level operations such as launching activities, broadcasting and receiving intents, etc
&&&&从上可知一下三点,即:
&&&&&&& 1、它描述的是一个应用程序环境的信息,即上下文。
&&&&&&&&2、该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
&&&&&&& 3、通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent
&&&& &信息&等。。
&& 于是,我们可以利用该Context对象去构建应用级别操作(application-level operations) 。
&一、Context相关类的继承关系
&&&&&&&&&&&&&&&&&&&&&&& &
& 相关类介绍:
&& Context类& & 路径: /frameworks/base/core/java/android/content/Context.java
&&&&&&&&&&&&说明:& 抽象类,提供了一组通用的API。
&&&&& 源代码(部分)如下:&&&
public&abstract&class&Context&{&&&&&&&...&&&&&&&public&abstract&Object&getSystemService(String&name);&&&&&&&&&public&abstract&void&startActivity(Intent&intent);&&&&&&&&&&&&public&abstract&ComponentName&startService(Intent&service);&&&&&&&&&&&&&&&&public&abstract&SharedPreferences&getSharedPreferences(String&name,int&mode);&&&&&&&...&&}&&
&&ContextIml.java类& 路径 :/frameworks/base/core/java/android/app/ContextImpl.java
&&&&&&&&& 说明:该Context类的实现类为ContextIml,该类实现了Context类的功能。请注意,该函数的大部分功能都是直接调用
&&&&& 其属性mPackageInfo去完成,这点我们后面会讲到。&&&&
&&&&&&&& 源代码(部分)如下:
&&&&&class&ContextImpl&extends&Context{&&&&&&&&&&&&&ActivityThread.PackageInfo&mPackageI&&&&&&&&&&&&@Override&&&&&&public&Object&getSystemService(String&name){&&&&&&&&&&...&&&&&&&&&&else&if&(ACTIVITY_SERVICE.equals(name))&{&&&&&&&&&&&&&&return&getActivityManager();&&&&&&&&&&}&&&&&&&&&&&else&if&(INPUT_METHOD_SERVICE.equals(name))&{&&&&&&&&&&&&&&return&InputMethodManager.getInstance(this);&&&&&&&&&&}&&&&&&}&&&&&&&@Override&&&&&&public&void&startActivity(Intent&intent)&{&&&&&&&&&&...&&&&&&&&&&&&&&&&&&&&mMainThread.getInstrumentation().execStartActivity(&&&&&&&&&&&&&&getOuterContext(),&mMainThread.getApplicationThread(),&null,&null,&intent,&-1);&&&&&&}&&}&&
&&ContextWrapper类 路径 :\frameworks\base\core\java\android\content\ContextWrapper.java
&& && &&说明: 正如其名称一样,该类只是对Context类的一种包装,该类的构造函数包含了一个真正的Context引用,即ContextIml
&&&&&&&对象。&&& 源代码(部分)如下:
public&class&ContextWrapper&extends&Context&{&&&&&&Context&mB&&&&&&&&&&&&&&&&&&&&protected&void&attachBaseContext(Context&base)&{&&&&&&&&&&if&(mBase&!=&null)&{&&&&&&&&&&&&&&throw&new&IllegalStateException(&Base&context&already&set&);&&&&&&&&&&}&&&&&&&&&&mBase&=&&&&&&&}&&&&&&@Override&&&&&&public&void&startActivity(Intent&intent)&{&&&&&&&&&&mBase.startActivity(intent);&&&&&&&&}&&}&&
ContextThemeWrapper类 路径:/frameworks/base/core/java/android/view/ContextThemeWrapper.java
&&& &&说明:该类内部包含了主题(Theme)相关的接口,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,
&& 所以Service直接继承于ContextWrapper类。
&&&&& 源代码(部分)如下:
public&class&ContextThemeWrapper&extends&ContextWrapper&{&&&&&&&&&&&&&&&&&&&&&private&Context&mB&&&&&&&&&&&&&public&ContextThemeWrapper(Context&base,&int&themeres)&{&&&&&&&&&&&&&&super(base);&&&&&&&&&&&&&&mBase&=&&&&&&&&&&&&&&&mThemeResource&=&&&&&&&&}&&&&&&&&&@Override&&&&&&&protected&void&attachBaseContext(Context&newBase)&{&&&&&&&&&&&&&&super.attachBaseContext(newBase);&&&&&&&&&&&&&&mBase&=&newB&&&&&&&}&&}&&
&&&& Activity类 、Service类 、Application类本质上都是Context子类, 更多信息大家可以自行参考源代码进行理解。
二、 什么时候创建Context实例&
&&&&&&熟悉了Context的继承关系后,我们接下来分析应用程序在什么情况需要创建Context对象的?应用程序创建Context实例的
&情况有如下几种情况:
&&&&& 1、创建Application 对象时, 而且整个App共一个Application对象
&&&&& 2、创建Service对象时
&&&&& 3、创建Activity对象时
&&& 因此应用程序App共有的Context数目公式为:
&&&&&&&&&&&&&&&&&&&& 总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例)
& 具体创建Context的时机
&&&& 1、创建Application对象的时机
&&&&& &每个应用程序在第一次启动时,都会首先创建Application对象。如果对应用程序启动一个Activity(startActivity)流程比较
清楚的话,创建Application的时机在创建handleBindApplication()方法中,该函数位于 ActivityThread.java类中 ,如下:
&&private&final&void&handleBindApplication(AppBindData&data){&&&&&&...&&&&&&&&&&&&Application&app&=&.makeApplication(data.restrictedBackupMode,&null);&&&&&&...&&}&&&&public&Application&makeApplication(boolean&forceDefaultAppClass,&Instrumentation&instrumentation)&{&&&&&&...&&&&&&try&{&&&&&&&&&&java.lang.ClassLoader&cl&=&getClassLoader();&&&&&&&&&&ContextImpl&appContext&=&new&ContextImpl();&&&&&&&&&&&&&&appContext.init(this,&null,&mActivityThread);&&&&&&&&&&&&&&&&&&&&&&app&=&mActivityThread.mInstrumentation.newApplication(&&&&&&&&&&&&&&&&&&cl,&appClass,&appContext);&&&&&&&&&appContext.setOuterContext(app);&&&&&&&&}&&&&&&&...&&}&&
&&& 2、创建Activity对象的时机
&&&&&& 通过startActivity()或startActivityForResult()请求启动一个Activity时,如果系统检测需要新建一个Activity对象时,就会
&&回调handleLaunchActivity()方法,该方法继而调用performLaunchActivity()方法,去创建一个Activity实例,并且回调
&onCreate(),onStart()方法等, 函数都位于 ActivityThread.java类 ,如下:
&&private&final&void&handleLaunchActivity(ActivityRecord&r,&Intent&customIntent)&{&&&&&&...&&&&&&Activity&a&=&performLaunchActivity(r,&customIntent);&&&&}&&private&final&Activity&performLaunchActivity(ActivityRecord&r,&Intent&customIntent)&{&&&&&&...&&&&&&Activity&activity&=&null;&&&&&&try&{&&&&&&&&&&&&&&&&&&&&java.lang.ClassLoader&cl&=&r.packageInfo.getClassLoader();&&&&&&&&&&activity&=&mInstrumentation.newActivity(cl,&component.getClassName(),&r.intent);&&&&&&}&&&&&&if&(activity&!=&null)&{&&&&&&&&&&ContextImpl&appContext&=&new&ContextImpl();&&&&&&&&&&&&&&&&appContext.init(r.packageInfo,&r.token,&this);&&&&&&&&&&&&&appContext.setOuterContext(activity);&&&&&&&&&&&&&&&&&&&&&&...&&&&&&}&&&&&&...&&&&&&}&&
3、创建Service对象的时机
&&&&& &通过startService或者bindService时,如果系统检测到需要新创建一个Service实例,就会回调handleCreateService()方法,
&完成相关数据操作。handleCreateService()函数位于 ActivityThread.java类,如下:
&&private&final&void&handleCreateService(CreateServiceData&data){&&&&&&...&&&&&&&&&&&&Service&service&=&null;&&&&&&try&{&&&&&&&&&&java.lang.ClassLoader&cl&=&packageInfo.getClassLoader();&&&&&&&&&&service&=&(Service)&cl..name).newInstance();&&&&&&}&catch&(Exception&e)&{&&&&&&}&&&&&&...&&&&&&ContextImpl&context&=&new&ContextImpl();&&&&&&&context.init(packageInfo,&null,&this);&&&&&&&&&&&&&&&Application&app&=&packageInfo.makeApplication(false,&mInstrumentation);&&&&&&&&&&&&context.setOuterContext(service);&&&&&&...&&}&&
另外,需要强调一点的是,通过对ContextImp的分析可知,其方法的大多数操作都是直接调用其属性mPackageInfo(该属性类
型为PackageInfo)的相关方法而来。这说明ContextImp是一种轻量级类,而PackageInfo才是真正重量级的类。而一个App里的
所有ContextIml实例,都对应同一个packageInfo对象。
&&&&&&&&&&&&
& && 最后给大家分析利用Context获取SharedPreferences类的使用方法,SharedPreferences类想必大家都使用过,其一般获取方
法就是通过调用getSharedPreferences()方法去根据相关信息获取SharedPreferences对象。具体流程如下:
&&& 1 、调用& getSharedPreferences()获取对应的的文件,该函数实现功能如下:
&&private&static&final&HashMap&File,&SharedPreferencesImpl&&sSharedPrefs&=&&&&&&&&&&new&HashMap&File,&SharedPreferencesImpl&();&&&&&@Override&&public&SharedPreferences&getSharedPreferences(String&name,&int&mode){&&&&&&&&&&&&&&SharedPreferencesImpl&&&&&&&&&&File&f&=&getSharedPrefsFile(name);&&&&&&&&&synchronized&(sSharedPrefs)&{&&&&&&&&&&&&&&&&&&sp&=&sSharedPrefs.get(f);&&&&&&&&&&&if&(sp&!=&null&&&&!sp.hasFileChanged())&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return&&&&&&&&&&&&}&&&&&&&}&&&&&&&&&&&&&&Map&map&=&null;&&&&&&&if&(f.exists()&&&&f.canRead())&{&&&&&&&&&&&try&{&&&&&&&&&&&&&&&str&=&new&FileInputStream(f);&&&&&&&&&&&&&&&map&=&XmlUtils.readMapXml(str);&&&&&&&&&&&&&&&str.close();&&&&&&&&&&&}&&&&&&&&&&&&...&&&&&&&}&&&&&&&&&&&&&&synchronized&(sSharedPrefs)&{&&&&&&&&&&&if&(sp&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp.replace(map);&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&sp&=&sSharedPrefs.get(f);&&&&&&&&&&&&&&&if&(sp&==&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sp&=&new&SharedPreferencesImpl(f,&mode,&map);&&&&&&&&&&&&&&&&&&&&&sSharedPrefs.put(f,&sp);&&&&&&&&&&&&&&&}&&&&&&&&&&&}&&&&&&&&&&&return&&&&&&&&}&&}&&
&& 2、 SharedPreferences 不过是个接口,它定义了一些操作xml文件的方法,其真正实现类为SharedPreferencesImpl ,该类是
&&& ContextIml的内部类,该类如下:
&&&&private&static&final&class&SharedPreferencesImpl&implements&SharedPreferences{&&&&&&&private&Map&mM&&&&&&&&&&&&&&&&&&&&&&&public&String&getString(String&key,&String&defValue)&{&&&&&&&&&&&synchronized&(this)&{&&&&&&&&&&&&&&&String&v&=&(String)mMap.get(key);&&&&&&&&&&&&&&&return&v&!=&null&?&v&:&defV&&&&&&&&&&&}&&&&&&&}&&&&&&&...&&&&&&&&&&&&&&public&final&class&EditorImpl&implements&Editor&{&&&&&&&&&&&private&final&Map&String,&Object&&mModified&=&Maps.newHashMap();&&&&&&&&}&&}&&
转载出处 :
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:265540次
积分:4823
积分:4823
排名:第4097名
原创:181篇
转载:31篇
评论:66条
阅读:19558
文章:23篇
阅读:59950
文章:107篇
阅读:173772
(5)(10)(8)(18)(17)(20)(9)(11)(18)(41)(53)(4)&&&&Android开发--入门经典
Android开发--入门经典
Android Android Android Android学习笔记 一 一 一
一 . . . .Android Android Android Android基础 基础 基础 基础
一. Android 的体系结构图
四层 , 底层 linux 内核(驱动) , 程序包(C 或 c++)和 Android 运行时(java 类似) ,应用程序框
架 (基本 API) , 应用程序层 .. 向下调用关系 .
二 , 王国历史
05 年 google 收购成立仅 22 个月的 android 公司 ,
07 年 11 月 google 为首的 34 家公司成立了开放手机联盟
08 年 9 月 T-moblie usa 发布第一款手机 T-moblic G1
三 , 开发精神 (随时随地为每个人提供信息)
开发平台普及 (pc,mac,linux) 以 linux 为基础 , java 语言,, 支持 web 下载应用
四 , 开发中的四大天王
Activity (构造应用程序界面的) 门面
Intent (程序传递数据)
Service (处理大部分数据工作)
Content provider (提供数据的接口)
五 , 开发的工具 SDK , eclipse (插件支持 ADT)
六 , 环境搭建
1 . Android SDK 安装
2. ADT 安 装 www.ecplise.org 在 ecplise 中 软 件 更 新 一 栏 填 入
https://dl-/android/eclipse
3. 在 eclipse 的首选项 android 中选择 android 的 location 填入本地 android SDK 的安装路径
4. 创建一个新的 android 的虚拟机 打开 android SDK and AVD manager
介绍一个很好的视频网站及资料站
www.(作者网站)
二 二 二 二 . . . . 工程创建及目录结构 工程创建及目录结构 工程创建及目录结构 工程创建及目录结构
一 , 新建 project
New -& android project -& project name -& build target (开发的版本选择)-& apllcation name
-& package name -& create activity(显示界面) -& min sdk version(最低兼容 sdk 版本)
二 , android 程序的目录结构
Src ==& 编写的源文件
Gen ==& 引用程序的资源文件 (不要修改)
Android ==& 源文件 jar 文件
Assets ==& 放置任何文件
Res ==& 此处放置会在 gen 中生成相应 ID
Drawable 放置图片 分为多个分辨率图片 hdpi,ldpi,mdpi 高中低
Layout 布局方式
adnroidManifest.xml 全局配置文件
三 三 三 三 . . . .Activity Activity Activity Activity初步 初步 初步 初步
1 . Activity 的主要作用(UI) 应用程序组件
创建一个 activity 类
创建 Activity 要点
1. 一个 activity 就是一个类, 并且这个类要继承 activity
2. 需要从写 onCreate 方法(程序运行首先调用)
3. 在配置文件中注册每一个 activity
4. 要为 activity 中添加必要的控件
5. 对应布局文件 一个布局文件对应一个 activity
得到控件 例 findViewById(R.id.MyButton);
四 四 四 四 . . . .Activity Activity Activity Activity和 和 和 和intent intent intent intent
多个 Activity 之间的关系
跳转关键 startActivity(Intent intent)
在 onClickListener 监听器的 onClick 方法中
内部类继承 OnClickListener
Intent intent = new Intent();
intent.putExtra(key , value); // 设置传参数据
intent.setClass(this,class); // 设置跳转参数
Activity.this.startActivity(intent);
myButton = (Button)findViewById(R.id.myButton);
myButton.setOnClickListener(new 内部类名()); // 注册成功
Intent 对象的获取
Intent intent = getIntent();
String value = intent.getStringExtra(key);
TextView = (TextView)findViewById(R.id.myTextView);
TextView.setText(value);
Intent 的基本作用
Intent 对象包含了一组信息 相当于一个请求
1. Component name (欲启动 Activity 的名称等等)
2. Action (另一个 Activity 的动作) ACTION_CALL EDIT , MAIN, SYNC, BATTERY_LOW , SCREEN_ON
3. Data (传递的数据)
4. Category
5. Exreas (额外的键值对信息)
启动另一个 Activity
例 Url url = Url.parse(&smsto://&);
Intent intent = new Intent(Intent.ACTION_SENDTO,url);
intent.putExtra(&sms_body&,&The SMS text&);
startActivity(intent); 五 五 五
五 . . . .Android Android Android Android开发时常用控件 开发时常用控件 开发时常用控件 开发时常用控件( ( ( (一 一 一 一) ) ) )
TextView , Button , EditText , Menu
例 , 实现一个简单的计算器功能
实现过程一 1 . 在第一个 Activity 中,声明 4 个控件 (2 个编辑框 , 1 个文本域 , 1 个按钮)
2. 要为其中的两个空间设置显示的值 (文本域 和 按钮)
3. 创建一个监听器 . 监听按钮事件
4. 将监听器对象绑定到按钮对象上
在布局的 xml 文件中添加控件 例:
Android:id=&@+id/eText1&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:id=&@+id/tView&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:id=&@+id/eText2&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:id=&@+id/bBtn&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
在使用空间的 Activity 页面中取出控件
例: public class Activity extends Activity {
Private EditText eText1;
Private EditText eText2;
Private TextView tV
Privete Button bB
Public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 根据控件的 ID 来取得代表控件的对象
eText1 = (EditText)findViewById(R.id.eText1);
eText2 = (EditText)findViewById(R.id.eText2);
tView = (TextView)findViewById(R.id.tView);
tView,setText(&乘以&);
bBtn = (Button)findViewById(R.id.bBtn);
bBtn.setText(&计算&); // 为 button 设置值
// 或设置在 res/strings.xml 中设置
//例 : &string name=&bBtnText&&计算&/string&
//bBtn.setText(R.string.bBtnText);
// 将监听器对象绑定按钮对象上去
bBtn.setOnClickLinstrener(new CalculateListener());
// 内部类监听器
Class CalculateListener implements OnClickListener {
Public void onClick(View v) {
// 取得两个编辑框的值
String eText1 = eText1.getText().toString();
String eText2 = eText2.getText().toString();
// 将两个值放入到 Intent 对象之中
Intent intent = new Intent();
// 使用这个 Intent 对象启动下一个 Activity
intent.putExtra(&one&,eText1 );
intent.putExtra(&two&,eText2);
intent.setClass(Activity.this , ResultActivity.class);
Activity.this.startActivity(intent);
实现过程二 :
1. 接受从 Activity 当中传递的值
2. 计算两个值的积
3. 将计算的结果显示在当前的 Activity 中
//在当前的 Activity 中的 xml 文件中添加一个文本域
Android:id=&@+id/tViewResult&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
在 onCreate 中执行语句 (不再累赘)
关键代码: // 取到 RestltView 的对象
Intent intent = getIntent();
String tText1 = intnet.getStringExtra(&one&);
String tText2 = intnet.getStringExtra(&two&);
Int tText1int = Integer.parseInt(tText1);
Int tText2int = Integer.parseInt(tText2);
Int result = tText1int * tText2
RestltView.setText(result + &&);
Menu 对象的实现
复写函数 onCreateOptionMenu()
Public boolean onCreateOptionMenu(Menu menu) {
// 第二个参数就是 itemid
Menu.add(0,1,1,R.string.exit);
Menu.add(0,2,2,R.string.about);
Return super.onCreate
继续实现 menuitem 的事件方法
// 当用户点击菜单的某一选项时,会调用该方法
复写 onOPtionsItemSelected(MenuItem item);
Public boolean onOPtionsItemSelected(MenuItem item) {
If(item.getItemId() == 1) {
Return super.onOptionsItemSelected(MenuItem item);
六 六 六 六 . . . .Activity Activity Activity Activity的生命周期 的生命周期 的生命周期 的生命周期
参考文档 : 安装目录/docs/index.html
Activity 的生命周期函数
onCreate (Activity 被第一个创建时), onReStart , onStart(Activity 可视的时候) , onDestroy ,
onPause (Activity 暂停状态), onResume (Activity 可被获得焦点的时候), onStop(Activity 不可见的
启动一个新的 Activity 会依次调用 onCreate , onStart , onResume
调用另外一个 Activity 会依次调用 onPause(第一个) , onCreate (第二个), onStart (第二个),
onResume(第二个) , onStop(第一个)
调用返回按钮 Activty 会依次调用 onPause (第二个) , onReStart(第一个) , onStart (第一个),
onResume(第一个), onStop(第二个) , onDestory (第二个)
onDestory()被调用的时机 1. 明确调用 finish 方法 2. 系统自适应释放
Task 基本概念 (栈中的所有 Activity) 栈 压栈,弹栈 (后进先出原则)
Task 运行过程 , 当应用程序启动之后,运行第一个 Activity 被压入栈中 (显示会时栈中最顶部的
3 . 模态化窗体(对话框)
在 AndroidManifest.xml 文件中 &Activity android:name=&.MofityActivity&
android:label=&MofityActivity&
android:theme=&@anroid:style/Theme.Dialog&
可被杀死的方法 onStop , onPause , onDestory
七 七 七 七 . . . .Activity Activity Activity Activity的布局 的布局 的布局 的布局
LinearLayout TableLayout
&LinearLayout xmlns:android=&/apk/res/android&
Android:orientation=&horizeontal&
Android:layout_width=&fill_parent&
Android:layout_height=&fill_parent&&
&TextView android:id=&@+id/firstView&
Android:text -- 指定文本内容
Android:grivity -- 基本位置 eng
Android:textSIze -- 文字大小 pt
Android:background -- 背景颜色 #fff
Android:width
Android:height
Android:padding --控件内边距 dip
Android:sigleLine -- 控件的内容是否在同一行显示 boolean
Android:weight -- 控件占 linearlayout 的比例
Android:layout_width
Android:layout_height
&/LinearLayout&
2 . &TableLayout android:stretchColumns=&1&& // 指定列拉伸
&TableRow&
// 填写控件
&/TableRow&
&TableRow&
&/TableRow&
&/TableLayout&
3 . LinearLayout 高级布局
例 : 思想 3 个 LinearLayout
&LinearLayout xmlns:android=&/apk/res/android&
Android:orientation=&vertical& -- 垂直布局
Android:layout_width=&fill_parent&
Android:layout_height=&fill_parent&
&LinearLayout
Android:orientation=&horizontal& -- 水平布局
Android:layout_width=&fill_parent&
Android:layout_height=&fill_parent&
Android:layout_weight=&1& -- 比例相等
&/LinearLayout&
&LinearLayout
Android:orientation=&vertical& -- 垂直布局
Android:layout_width=&fill_parent&
Android:layout_height=&fill_parent&
Android:layout_weight=&1&
&/LinearLayout&
&/LinearLayout&
注 : 在 LinearLayout 中还可以嵌套 TableLayout
4 . RelativeLayout 相对布局
Relative 常见属性的概要
Android:layout_above -- 将该控件的底部至于给定 ID 的控件之上
Android:layout_Below -- 将该控件的底部至于给定 ID 的控件之下
Android:layout_toLeftOf -- 该控件的右边缘个给定 ID 的控件的左边缘对齐
Android:layout_toRightOf -- 该控件的左边缘个给定 ID 的控件的右边缘对齐
Layout_alignBaseline -- 该控件的 baseline 与给定 ID 的控件的 baseline 对齐
Layout_alignBottom -- 该控件的底部边缘与给定 ID 的控件的底部边缘对齐
Layout_alignLeft -- 该控件的左边缘个给定 ID 的控件的左边缘对齐
Layout_alignRight -- 该控件的右边缘个给定 ID 的控件的右边缘对齐
Layout_alignTop -- 该控件的顶部边缘与给定 ID 的控件的顶部边缘对齐
Layout_alignParentBottom , Layout_alignParentLeft , Layout_alignParentRight ,
Layout_alignParentTop 该值为 True 时 , 该控件的边与父控件的边的对齐方式
Layout_centerHorizontal , Layout_centerInParent , Layout_centerVertical
&RelativeLayout xmlns:anroid=&/apk/res/android&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:padding=&10px& &
&TextView Android:id=&@+id/label&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:text=&Type Here:& /&
&EditText Android:id=&@+id/entry&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:background=&@android:dravable/editbox_background& -- 默认编辑框的颜色
Android:layout_below=&@id/label& /&
&Button Android:id=&@+id/ok&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:layout_below=&@id/entry&
Android:layout_alignParentRight=&true&
Android:layout_marginLeft=&10px&
Android:text=&OK& /&
&Button Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:layout_toLeftOf=&@id/ok&
Android:layout_alignTop=&@id/ok&
Android:text=&Cancal& /&
&/RelativeLayout& 八 八 八
八 . . . .Android Android Android Android开发时常用控件 开发时常用控件 开发时常用控件 开发时常用控件( ( ( (二 二 二 二) ) ) )
RadioGroup , RadioButton
例 1 , &RadioGroup Android:id=&@+id/genderGroup&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:orientation=&vertical& &
&RadioButton Android:id=&@+id/female&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:text=&@string/female& /&
&RadioButton Android:id=&@+id/male&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:text=&@string/male& /&
&/RadioGroup&
代码 : 1. 控件对象声明
2. 取得对象控件
3. 设置监听器 ( 只为 RadioGroup 注册一个 )
Public void onCheckedChange(RadioGroup group , int checkedId) {
If (femaleButton.getId() == checkedId) {
System.out.println(&Female&);
Else if (maleButton.getId() == checkedId) {
System.out.println(&Male&);
4. 触发事件
// 为 RadioGroup 设置
RadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() )
例 2 . &CheckBox android:id=&@+id/swim&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:text=&@string/swim& /&
&CheckBox android:id=&@+id/run&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:text=&@string/run& /&
&CheckBox android:id=&@+id/read&
Android:layout_width=&wrap_content&
Android:layout_height=&wrap_content&
Android:text=&@string/read& /&
代码 : 1. 控件对象声明
2. 取得对象控件
3. 设置监听器(为每一个 CheckBox 注册监听器)
Public void onCheckedChanged(CompoundButton buttonView , boolean isChecked) {
If(isChecked) {
System.out.println(&yes&);
System.out.println(&NO&);
4. 触发事件
CheckBox.setOnCheckedChangeLinstener(new CompoundButton.onCheckedChangeLinstener() {})
例 3 . Toast
Toast.makeText(this.class , displaystring , messageTime).show()
九 九 九 九 . . . .Android Android Android Android开发时常用控件 开发时常用控件 开发时常用控件 开发时常用控件( ( ( (三 三 三 三) ) ) )
ProgressBar
例 : &ProgressBar android:id=&@+id/pBar&
Style=&?Android:attr/progressBarStyleHorizontal& -- 水平方向的进度条
Android:layout_width=&200dp&
Android:layout_height=&wrap_content&
Android:visibility=&gone&
Android:max=200
代码 : 1 . 声明变量
2 . 根据 ID 取得控件对象 findViewById
3 . 设置监听类
Class ButtonLinstener implements OnClickListener {
Public void onClick(View v) {
If (i == 0) {
pBar.setVisibility(View.VISIBLE);
Else if ( i & pBar.getMax() ) {
pBar.setProgress(i); -- 设置主进度条的当前值
pBar.setSecondaryProgress(i+10); -- 设置第二进度条的当前值
pBar.setVisbility(View.GONE);
I = i + 10;
4 . 绑定事件
myButton.setOnClickListener(new ButtonLinstener());
例 : main 布局文件
&ListView android:id=&@id/android:list&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:drawSelecrorOnTop = &false&
Android:scrollbars=&vertical& /&
User 布局文件略 (两个 TextView)
代码 : public class Activity extends ListActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 用一个集合对象装数据
ArrayList&HashMap&Stirng,String&& list = new ArrayList&HashMap&Stirng,String&&();
HashMap&String,String& Map1 = new HashMap&String,String&();
HashMap&String,String& Map2 = new HashMap&String,String&();
HashMap&String,String& Map3 = new HashMap&String,String&();
Map1.put(&user_name&,&zhangsan&);
Map1put(&user_ip&,&192.168.0.1&);
Map2.put(&user_name&,&lisi&);
Map2.put(&user_ip&,&192.168.0.2&);
Map3.put(&user_name&,&wangwu&);
Map3.put(&user_ip&,&192.168.0.3&);
List.add(Map1);
List.add(Map2);
List.add(Map3);
// listActivity 对象 , map , 第二个布局文件 , 对应 hashMap 的值对(可想象成列) , 控件显示的位置
SimpleAdapter listAdapter = new SimpleAdapter(this , list , R.layout.user , new String[]
{&user_name&,&user_ip&} , new int[] {R.id.user_ip,R.id.user_name});
setListAdapter(listAdapter);
Protected void onListItemClick(ListView lv , View v , int position , long id) {
super.onListItemClick(1, v , position , id);
System.out.println(&id--------& + id);
System.out.println(&position-------& + position)
十 十 十 十 . . . .Handler Handler Handler Handler的用法 的用法 的用法 的用法
Handler 的基本概念 (可以进行另外线程的处理程序 , 优化程序 , 类似于线程概念)
异步线程处理方案
Handler 基本的使用方法
代码 : 可以在事件中调用 Handler 的方法
例 : 在 Button 的单击事件中:
Handler.post(updateThread); // 线程对象加入到消息队列中, 此消息队列中只有一个线程对象
// 取消线程队列
handler.removeCallbacks(updateThread);
// 创建一个 Handler 对象
Handler handler = new Handler();
// java 中实现线程的方法 1 继承 thread 类 2.实现 runnable 接口
// 将要执行的操作写在线程对象的 run 方法中去
Runnable updateThread = new Runnable (){
Public void run() {
System.out.println(&UpdateThread&);
// 在 run 方法内部执行 postDelayed 或者 post 方法
handler.postDelayed(updateThread , 3000); // 延迟加入消息队列
// 消息队列(数据结构) 先进先出
使用 Handler 更新 ProgressBar
例 : main.xml 中的布局
&LinearLayout xmlns=&/apk/res/android&
Android:orientation=&vertical&
Android:layout_width=&fill_parent&
Android:layout_height=&fill_oarent& &
&ProgressBar android:id=&@+id/pBar&
Style=&?android:attr/progressBarStyleHorizontal&
Android:layout_width=&200dp&
Android:layout_height=&wrap_content&
Android:visibility=&gone& /&
&Button android:id=&@+id/StartButton&
Android:layout_width=&fill_parent&
Android:layout_height=&wrap_content&
Android:text=&start& /&
&/LinearLayout&
Activity 中的代码:
Public class TestBarHandler extends Activity {
// 声明控件对象
ProgressBar bar =
Button startButton =
Public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 得到控件对象
Bar = (ProgressBar)findViewById(R.id.bar);
startButton = (Button)findViewById(R.id.startButton);
// 为按钮设置监听器
startButton.setOnClickListener(new ButtonListener());
// 创建监听器
Class ButtonListener implements OnClickLinstener {
Public void onClick(View v) {
pBar.setVisibility(View.VISIBLE);
pBar.setMax = 200;
updateBarHandler.post(updateThread);
// 创建一个 Handler 对象 使用匿名内部类来复写 handler 的 handlerMessage 中
Handler updateBarHandler = new Handler() {
Public void handlerMessage(Message msg) {
bar.setProgress(mag.arg1);
updateBarHandler.post(updateThread); // 线程加入线程队列中
// 匿名内部线程类
Runnable updateThread = new Runnable(){
Int i = 0 ;
Public void run() { // 直接执行了当前 Activity 的线程
System.out.println(&begin Thread&);
I = i +10;
// 得到一个消息对象 , message 类是有 android 操作系统提供
Message msg = updateBarHandler.obtainMessage();
// 将 msg 对象的 arg1 参数的值设置为 i , 用 arg1 和 arg2 这两个成员变量传递消息,可以使系统的性能
Msg.arg1 =
Thread.sleep(1000);
} catch ( InterruptedException e) {
e.printStackTrace();
// 将 msg 加入消息队列中
updateBarHandler.sendMessage(msg);
If(i == pBar.getMax()) {
// 如果 i 的值到达最大值时,移除线程
updateBarHandler.removeCallbacks(updateThread);
4 . Handler 与线程 (默认情况下 Activity 与 Handler 共享一个线程)
例 : // 证明 Activity 与 Hnadler 共享一个线程
Public class HnadlerTest extends Activity {
private Handler handler = new Handler();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // 执行完这一行代码 Activity 中才有控件
Handler.post(r);
//Thread t = new Thread(r); // 独立线程
//t.start();
// currentThread 得到当前运行线程对象
System.out.println(&activity-----&& + Thread.currentThread().getId());
System.out.println(&activityname-----&& + Thread.currentThread().getName());
Runnable r = new Runnable() {
Public void run () {
System.out.println(&Handler-----&& + Thread.currentThread().getId());
System.out.println(&HandlerName-----&& + Thread.currentThread().getName());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
// 输出对比 需要等待 10 秒,Activity 中才会有控件
Activity----& 1
ActivityName ---& main
Handler----& 1
HandlerName ---& main
// 独立线程输出 无等待时间
Handler ---& 9
HandlerName ---& Thread-9
Activity----& 1
ActivityName ---& main
5 . Bundle 的用法(相对特殊的 map , key 一般为 string , value 为个个数据类型)
// Looper , handlerThread 都可以创建一个新的线程
例 : Public class HnadlerTest extends Activity {
private Handler handler = new Handler();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println(&Activity ----& & + Thread.currentThread().getId());
// 生成一个 HandlerThread 对象,实现了使用 looper 来处理消息队列的功能,这个类有 android 内部实现
HandlerThread handlerThread = new HandlerThread();
handlerThread.start();
MyHandler myHandler = new MyHandler(handlerThread.getLooper());
// 获取消息对象
Message msg = myHandler.obtainMessage();
msg.sendToTarget();
Class MyHandler extends Handler {
Public MyHandler () {
Public MyHnadler(Looper looper) {
// 调用父类的构造函数 , 有 looper 的方法
Super(looper);
Public void handleMessage(Message msg) {
System.out.println(&handler----&& + Thread.currentThread().getId());
System.out.println(&HandlerMessage&);
6 . 在新线程当中处理消息的方法
// 首先创建 Message 对象
// 可以用 arg1 , arg2 (int) , obj (object) , setData(Bundle data) 赋值传递
// 取值 变量 = msg.arg1 等等
Bundler 例 : // 赋值
Bundle b = new Bundle();
b.putInt(&age&,20);
b.putString(&name& , &zhangsan&);
msg.setData(b);
Bundle b = msg.getData();
Int age = b.getInt(&age&);
String name = b.getString(&name&);
十一 十一 十一 十一 . . . .SQLite SQLite SQLite SQLite使用方法 使用方法 使用方法 使用方法
SQLite 介绍
http://www.sqlite.org 官方网站
小型关系数据库
SQLiteOpenHelper 使用方法
getReadableDatabase()
getWritableDatabase()
onCreate(SQLiteDatabase db)
onOpen(SQLiteDatabase db)
onUpgrade(SQLiteDatabse db , int oldVersion , int newVersion)
// DatabaseHelper 所为一个访问 SQLite 的助手类, 提供两个方面的功能
// 第一, getReadableDatabase() 和 getWritableDatabasr() 可以获得 SQLiteDatabase 对象
// 第二, 提供 onCreate 和 onUpgrade 两个回调函数 , 允许我们在创建和升级数据库时, 进行操作
例 : public class DatabaseHelper extends SQLiteOpenHelper {
// 数据库版本号
Private static final int VERSION = 1;
// 必须的构造函数
Public DatabaseHelper (Context context , String name , CursorFactory factory , int version) {
Super(context , name , factory , version);
Public DatabaseHelper (Context context , String name , int version) {
Super(context , name , null , version);
Public DatabaseHelper (Context context , String name) {
Super(context , name , null , VERSION);
Public void onCreate(SQLiteDatabase db) {
System.out.println(&create a database&);
Db.execSQL(&create table user(id int , name varchar(20))&);
Public void onUpgrade(SQLiteDatabase db) {
System.out.println(&update a database&);
对 SQLite 的增 删 查 改
Activity 操作数据库 例 :
1 . 声明控件对象(略)
2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象 (调用 DatabaseHelper)
// 创建一个数据库
Public void onClick(View v) {
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db&);
SQLiteDatabase db = dbHelper.getReadableDatabase(); // 此时才会创建一个数据库
// 修改一个数据库
Public void onClick(View v) {
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db& , 2); // 版本号
SQLiteDatabase db = dbHelper.getReadableDatabase();
// 插入操作
Public void onClick(View v) {
// 生成 ContentValues 对象
ContentValues values = new ContentValues();
// key 是列名 , value 是值 , 值必须对应数据库列数据类型
Values.put(&id& , 1);
Values.put(&name& , &zhangsan& );
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db&);
// 得到可写数据库
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 1.表名 2,不允许空列 3, 值
Db.insert(&user&, null , values);
// 更新操作
Public void onClick(View v) {
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db&);
// 得到可写数据库
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 1.表名 2,不允许空列 3, 值
// 生成 ContentValues 对象
ContentValues values = new ContentValues();
// key 是列名 , value 是值 , 值必须对应数据库列数据类型
Values.put(&name& , &zhangsanfeng& );
// 1.表名 2. 值 , 3 , where 子句 (不包括 where) 4, 为占位符赋值
Db.update(&user&, values , &id=?& , new String[] {&1&});
// 查询数据库
Public void onClick(View v) {
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db&); // 版本号变了
SQLiteDatabase db = dbHelper.getReadableDatabase();
// 1, 表名 2 所要查询的列名 3 , 筛选器 4 , 筛选器值 5 .groupby 6 . having //7 orderby
创建游标对象读取数据
Cursor cursor = db.query(&user& , &new String[] {&id& , &name&}& , &id=?&)
While (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(&name&));
System.out.println(&query---&& + name);
// 删除操作
Public void onClick(View v) {
// 当前的 activity , 还有数据名
DatabaseHelper dbHelper = new DatabaseHelper(SQLiteActivity.this , &test_db&);
// 得到可写数据库
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 1.表名 2. 值 , 3 , where 子句 (不包括 where) 4, 为占位符赋值
Db.delete(&user&, values , &id=?& , new String[] {&1&});
使用 adb 访问 SQLite (linux 命令行调试) abd shell = & ls -i = & cd data = & 创建了数据库之后 =
& 报名.数据库名 =& 即可进入该 SQLite
SQLite 语句 .schema // 查看所有表
Linux 知识补习 : cd 目录 (进入目录) ls (查看当前目录)
十二 十二 十二 十二 . . . . 程序调试 程序调试 程序调试 程序调试
1 . DDMS 的使用
LogCat 的 Verbose Debug Info Warning Error 的功能
增加过滤器 create filter =& system.out
通过 file explorer 功能实现文件的取出,放入
2 . 常见程序调试
A) 多多查看 DDMS 的 log 和 java 中的方式相同
B) 使用 Log 类输出各类信息
十三 十三 十三 十三 . . . . 文件下载 文件下载 文件下载 文件下载
1 . 使用 http 协议下载文件
A ) : 创建一个 HttpURLConection 对象
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
B ) : 获取一个 InputStream
urlConn.getInputStream();
C ) : 访问网络的权限
android.permission.INTERNET
例 : 1 . 声明控件对象(略)
2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
// 封装方法 httpDownloader
Public class HttpDownloader {
Private URL url =
Public String download(String urlStr) {
StringBuffer sb = new StringBuffer();
String line =
BufferedReader buffer =
// 创建一个 URL 对象
Url = new URL(urlStr);
// 创建一个 Http 连接
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
// 使用 IO 流读取数据
Buffer = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));
While ((line = buffer.readline()) != null) {
Sb.append(line);
} catch (Execption e) {
e.printStackTrace();
} finally {
Buffer.close();
} catch (Execption e) {
e.printStackTrace();
Return db.ToString();
// 返回值 -1 . 下载文件出错 0 下载成功 1 文件已存在
Public int downFile(String urlStr , String path , String fileName) {
InputStream inputStream =
FileUtils fileUtils = new FileUtils();
If(fileUtils.isFileExists(path + fileName)) {
InputStream = getInputStreamFromUrl(urlStr);
File resultFile = fileUtils.write2SDFromInput(path , fileName ,
inputStream);
If(resultFile == null) {
Return -1;
} catch (Exception e) {
e.printStackTrace();
Return -1;
} finally {
inputStream.close();
} catch (Execption e) {
e.printStackTrace();
// 根据 url 得到输入流
Public InputStream getInputStreamFromUrl (String urlStr)
Throws MalfromedURLExecption , IOExecption {
Url = new URL(urlStr);
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
InputStream inputStream = urlConn.getInputStream();
Return inputS
Public void onClick(View v) {
HttpDownloader httpDownloader = new HttpDownloader();
String lrc = httpDownloader.download(&http://192.168.0.1:8080/XXX.txt&);
System.out.println(lrc);
2 . 将下载的文件写入 SDCARD
访问 SDCARD
// 得到当前设备 sdka 的目录
Environment.getExternalStorageDirectory();
// 访问 SD 卡的权限
Android.permission.WRITE_EXTERNAL_STORAGE
例 : // 一个完整的访问封装类
Public class FileUtils {
Private String SDPATH;
Public String getSDPATH() {
Return SDPATH;
Public FileUtils() {
SDPATH = Environment.getExternalStorageDirectory() + &/&;
// 在 SD 卡上创建文件
Public File createSDFile(Stirng fileName) throws IOException {
File file = new File(SDPATH + fileName);
file.createNewFile();
// 在 SD 卡上创建目录
Public File createSDDir(String dirName) {
File dir = new File(SDPATH + dirName);
Dir.mkdir();
// 判断 SD 卡上的文件夹是否存在
Public boolean isFileExist (String fileName) {
File file = new File(SDPATH + fileName);
Return file.exists();
// 将一个 inputStream 里面的数据写入到 SD 卡上
Public file write2SDFromInput(String path , string fileName , InputStream input) {
File file =
OutputStream output =
createSDDir(path);
File = createSDFile(path + fileName);
Output = new FileOutPutStream(file);
Byte buffer [] = new byte [4 * 1024];
While ((input.read(buffer)) != -1) {
Output.write(buffer);
Output.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
Output.close();
} catch (Exception e) {
e.printStackTrace();
最后在 AndroidManifest,xml 中加入标签
&user-permission android:name=&android.permission. WRITE_EXTERNAL_STORAGE& /&
十四 十四 十四 十四 . . . .Content Content Content ContentProvider Provider Provider Provider
1.ContentProvider 基本概念 A:ContentProvider 提供为存储和获取数据提供了统一的接口 B: 使用 ContentProvider 可以在不同的应用程序之间共享数据 C:Android为常见的一些数据提供了ContentProvider(包括音频 , 视频,图片和通讯 录等等)
2.Uri A:每一个 ContnetProvider 都拥有一个公共的 URI,这个 URI 用于表示这 个 ContnetProvider 所提供的数据 B:Android 所提供的 ContentProvider 都存放在 android.provider 包当中 3.ContnetProvider 实现方法 Query Insert Update Delete getType onCreate 4. 实现 ContentProvider 的过程 A: 定义一个 Content_URI 常量 B: 定义一个类 , 继承 ContentProvider C: 实现 query,insertupdate,deletegetType,和 onCreate 方法; D: 在 AnroidManifest.xml 当中进行声明;
例 : // DatabaseHelper 所为一个访问 SQLite 的助手类, 提供两个方面的功能 // 第一, getReadableDatabase() 和 getWritableDatabasr() 可以获得 SQLiteDatabase 对象
// 第二, 提供 onCreate 和 onUpgrade 两个回调函数 , 允许我们在创建和升级数据库时, 进行操作
例 : public class DatabaseHelper extends SQLiteOpenHelper {
// 数据库版本号
Private static final int VERSION = 1;
// 必须的构造函数
Public DatabaseHelper (Context context , String name , CursorFactory factory , int version) {
Super(context , name , factory , version);
Public DatabaseHelper (Context context , String name , int version) {
Super(context , name , null , version);
Public DatabaseHelper (Context context , String name) {
Super(context , name , null , VERSION);
Public void onCreate(SQLiteDatabase db) {
System.out.println(&create a database&);
// 拼出了建表的语句 db..execSQL(&create table& + FirstMetaData.USER_TABLE_NAME +&(&+ FirstMetaData.UserTableMetaData._ID +&INTEGER PRIMARYKEYAUTOINCREMENT,& +FirstMetaData.UserTableMetaData.USER_NAME +&varchar(20));&; }
Public void onUpgrade(SQLiteDatabase db) {
System.out.println(&update a database&);
ContentProviderActivity 例 : 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
Public void onClick(View v) {
ContentValues values = new ContentValues (); Values.put(FirstMetaData.UserTableMetaData.USER_NAME , &zhangsan&); Uri uri = getContentesolver().insert(FirstMetaData.UserTableMetaData.CO NTENT_URI,values); System.out.println(&uri ----&& + uri.toString());
Public void onClick(View v) {
Cursor c= getContentResolver().query( FirstMetaData.UserTableMetaData.CONTENT_URI , null,null,null,null ) ;
While(c.moveToNext()) {
System.out.println(c.getString(c.getColumnIndex(UserTa
bleMeatData.USER_NAME)));
FirstContentProvider 继承 ContentProvider 例 :
PublicclassFirstContentProviderextendsContentProvider {
Publicstatic finalUriMatcheruriM Publicstatic finalintINCOMING_USER_COLLECTION =1; Publicstatic finalintINCOMING_USER_SINGLE =2; Private DatabaseH
Static { uriMatcher= newUriMatcher(UriMatcher.NO_MATCH); //URI 限定名的添加验证 定义了一个验证的规则 uriMatcher.addURI(FirstMetaData.AUTHORTY , &/users&, INCOMING_USER_COLLECTION); uriMatcher.addURI(FirstMetaData.AUTHORTY , &/users/#&, INCOMING_USER_SINGLE); }
Public static HashMap&String,String& userProjectionM
userProjectionMap = new HashMap&String,String&();
// ._ID 就是 baseColumns 实现的结果 userProjectionMap.put(FirstMetaData._ID,FirstMetaData._ID); userProjectionMap.put(FirstMetaData .USER_NAME , FirstMetaData.USER_NAME); }
Public int delete(Uri arg0 , String arg1 , String[] arg2) {
System.out.println(&delete&);
// 根据传入的 Uri,返回该 Uri 所表示的数据类型
Public String getType(Uri uri) {
System.out.println(&getType&);
Switch (uriMatcher.match(uri)) {
Case INCOMING_USER_COLLECTION: Return FirstMetaData.CONTENT_TYPE; CaseINCOMING_USER_SINGLE: ReturnFirstMetaData.CONTENT_TYPE_ITEM; Default: ThrownewIllegalArgumentExecption(&Unknown URI&+uri);
// 该函数的返回值是一个 Uri , 这个 URi 表示的是刚刚使用这个函数所插入的数据 // content://com.android.FirstContentProvider/users/1 @Override
Public Uri insert(Uri uri , ContentValue values) {
System.out.println(&insert&);
SQLiteDatabase db = dh.getWrittableDatabase(); Long rowId = db.insert(FirstMetaData.TABLE_NAME,null,values); If(rowId & 0) {
// 以 Content 起头的 Uri 都可以用 ContentUris 来处理
Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI ,
// 通知监听器 , 数据已经改变
getContext().getContentResolver().notifyChange(insertedUserUri , null);
Return insertedUserU
Throw new SQLExecption(&Failed to insert row into & + uri);
Public boolean onCreate() { Dh = new DatabaseHelper(getContext() , FirstMetaData.DATABASE_NAME); System.out.println(&onCreate&);
Public Cursor query(Uri uri , String[] projection , String selection , String[]
selectionArgs , String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder ();
Switch (uriMatcher.match(uri)) {
Case INCOMING_USER_COLLECTION: qb.setTables(FirstMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap);
B CaseINCOMING_USER_SINGLE: qb.setTables(FirstMetaData.TABLE_NAME); qb.setProjectionMap(userProjectionMap);
// 取回了单条数据 list qb.appendWhere(FirstMetaData._ID + &=&+uri.getPathSeqments().get(1)); B
String orderBy;
If (TextUtils.isEmpty(sortOrder)) { orderBy = FirstMetaData.DEFAULT_SORT_ORDER; } else {
orderBy = sortO
SQLiteDatabase db = dh.getWritableDatabase();
Cursor c = qb.query(db , projection , selection , selectionArgs , null , null , orderBy);
c.setNotificationUri ( getContext().getContentResolver() , uri);
System.out.println(&query&);
Public int update(Uri arg0 , ContentValues arg1 , String arg2 , String[] arg3) {
System.out.println(&update&);
FirstMetaData(一些静态常量) 例 :
PublicclassFirstMetaData { //URI 限定名的名称 包名 + 类名 Publicstatic finalStringAUTHORTY=&com.android.FirstContentProvider&; // 数据库名称 Publicstatic finalStringDATABASE_NAME=&FirstContentProvider.db&; // 数据库版本 Publicstatic finalintDATABASE_VERSION =1; // 表名 Publicstatic finalStrintUSERS_TABLE_NAME =&users&;
//BaseColumns 实现了表的_id 列 Publicstatic finalclassUserTableMetaDataimplementsBaseColumns{ // 表名 Publicstatic finalStringTABLE_NAME= &users&; // 访问该 ContentProvider 的 URI Public static final Uri CONTENG_URI = Uri.parse(&content://& + AUTHORY + &/users&); // 整张表的数据类型是 vnd.android.cursor.dir/vnd+ Public static final String CONTENT_TYPE = &vnd.android.cursor.dir/vnd.FinrstContentProvider.ser&; // 单条数据类型定义 vnd.android.cursor.item/vnd+name Public static final String CONTENT_TYPE_ITEM = &vnd.android.cursor.item/vnd.FinrstContentProvider.user&; // 列名 Publicstatic finalStringUSER_NAME=&name&; // 默认排序方法 Publicstatic finalStringDEFAULT_SORT_ORDER= &_iddesc&; }
最后在 androidMnaifest.xml 中注册 provider 与 Activity 同级 authorities 中的数据一定要 与 CONTENG_URI 的一致 &providerandroid:name=&com.android.FirstContentProvider& Android:authorities=&com.android.FirstContentProvider&/&
十五 十五 十五 十五 . . . .XML XML XML XML文件解析 文件解析 文件解析 文件解析
1. 什么是 SAX
SimpleAPI forXML, 既是指一种接口 , 也是指一个软件包 作为接口 ,SAX 是事件驱动型 XML 解析的一个标准接口
2.SAX 基本原理
SAX 的哦给你工作原理简单地说就是对文档进行顺序扫描,当扫描到文档 (document)开始与结束,元素(element)开始与结束等地方时通知事件处理函数,由事件处 理函数做相应动作,然后继续同样的扫描,直至文档结束.
大多数 SAX 实现都会产生一下类型的事件 { 在文档的开始和结束时出发文档处理事件 在文档内每一 XML 元素接受解析的前后触发元素事件 任何元数据通常都由氮素的事件交付 在处理文档的 DTD 或 Schema 时产生 DTD 或 Schema 事件
产生错误事件用来通知主机应用程序解析错误
3.SAX 常用接口
ContentHandler 接口 ContentHandler是java类包中一个特殊的SAX接口,位于org.xml.sax包中.该接 口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇 到某些特殊的事件,比如文档的开头和结束,元素的开头和结束,以及元素中的字符 数据等事件.当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方 法来响应该事件
ContnetHandler 接口的方法有以下几种 { Void startDocument();
Void endDocument();
Void startElement(String uri,StringlocalName ,stringqName ,Attributesatts)
Void endElement(Stringuri,String localName,StringqName)
Void characters(char[]ch,intstart,intlength)
4.SAX 解析 解析文档过程 例 :&doc& &para&HelloWorld!&/para& &/doc& 在解析文档的过程中会产生如下一系列事件
Startdocument { Startelement:doc A: 创建事件处理程序 Startelement:para Characters:HelloWorld! B: 创建 SAX 解析器 Endelement:para Endelement:doc C: 将事件处理程序分配给解析 器 D: 对文档进行解析 , 将每个 事件发送给处理程序 Enddocument }
解析样例 : 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
Public void onClick(View v) {
HttpDownloader hd = new HttpDownloader();
String resultStr = hd.download(&XMLURL&);
System.out.priintln(resultStr);
// 创建一个 SAXParseFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
// 为 XMLReader 设置内容处理器 MyContentHandler
reader.setContentHandler(new MyContenHandler());
// 开始解析文件 字符串构造成 reader 之后构造成 inputSource
Reader.parse(new InputSource(new StringReader(resultStr)));
} catch (Execption e) {
e.printStackTrace();
XML 文件写法 :
&wordkers&
&worker id=&AQ01&&
&name&mark&/name&
&sex&male&/sex&
&status&manager&/status&
&address&New York&/address&
&salary&$4000&/salary&
&worker id=&AQ02&&
&name&lily&/name&
&sex&female&/sex&
&status&assists&/status&
&address&H&/address&
&salary&$2000&/salary&
&worker id=&AQ03&&
&name&tom&/name&
&sex&male&/sex&
&status&manager&/status&
&address&F&/address&
&salary&$5000&/salary&
&/wordkers&
MyContenHandler 的写法 例 :
Public class MyContenHandler Extends DefaultHandler { // 此处体现了适配器模式
String Name , Sex , Status , Address , Salary
String tagN
// 开始 document
Public void startDocument() throws SAXExecption {
System.out.println(&-------begin--------&);
// 结束 document
Public void endDocument() throws SAXExecption {
System.out.println(&-------end--------&);
// 开始节点对象
Public void startElement(String namespaceURI , String localName , String qName ,
Attributes attr) throws SAXExecption {
tagName = localN
If (localName.equals(&worker&)) {
// 获取标签的全部属性
For (int i = 0 ; i & attr.getLength(); i ++) {
System.out.println(attr.getLocalName(i) + &=& + attr.getValue(i))
// 结束节点对象
Public void endElement(String namespaceURI , String localName , String qName ) throws
SAXExecption {
// 在一个标签解析完之后,打印所有标签的信息
If (localNmae.equals(&worder&)) {
This.printout();
// 读取文本对象
Public void characters(char[] ch , int start , int length) throws SAXExecption {
If (tagNmae.equals(&name&))
Hisname = new String(ch , start , length);
Else if (tagNmae.equals(&sex&))
Sex = new String(ch , start , length);
Else if (tagNmae.equals(&status&))
Status= new String(ch , start , length);
Else if (tagNmae.equals(&address&))
Address= new String(ch , start , length);
Else if (tagNmae.equals(&salary&))
Salary= new String(ch , start , length);
// 打印读出的信息
Public void printout() {
System.out.println(&name---&& + Name);
System.out.println(&name---&& + Sex);
System.out.println(&name---&& + Status);
System.out.println(&name---&& + Address);
System.out.println(&name---&& + Salary);
十六 十六 十六 十六 . . . . 广播机制 广播机制 广播机制 广播机制
1.Adnroid 的广播机制
2.BroadcastReceiver 的作用
事件触发之后的一种解决方法
3.BroadcasrReceiver 的编写方法 在 AndroidManifest.xml 中注册广播 &receiverandroid:name=&.TextReceiver&& &intent-filter& &actionandroid:name=&android.intent.action.EDIT&& &/intent-filter& &receiver&
例 ://BroadcasrReceiver PublicclassTestReceiverextendsBroadcastReceiver { PublicTestReceiver(){ System.out.println(&TestReceiver&); }
@override PublcvoidonReceive(Contextcontext,Intentintent){ System.out.println(&OnReceiver&); // 对象会被销毁 TestReceiver }
Activity 中的写法 例: 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
Publicvoid onClick(Viewv) { TestReceivertr= newTestReceiver(); Intentintent=newIntent(); intent.setAction(Intent.ACTION_EDIT); // 与 AndroidManifest 中的过滤内容 对比 TestActivity.this.sendBroadcast(intent); }
4.BroadcastReceiver 的生命周期
5. 注册 BroadcastReceiver 的方法
BroadcastReceiver 用 于 监 听 被 广 播 的 事 件 (Intent) 为 了 达 到 这 个 目 的,BroadcastReceiver 必须进行注册,以下是注册的两种方法
在应用程序的代码当中进行注册 注册 BroadcastReceiver registerReceiver(receiver,filter) 取消注册 UnregisterReceiver(receiver);
Activity 中代码 例 : 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
// 绑定广播事件
Publicvoid onClick(Viewv) { // 生成 receiver 对象 smsReceiver=newSMSReceiver(); IntentFilterfilter=newIntentFilter(); filter.addAction(&android.provider.Telephony.SMS_RECEIVED&); // 注册广播事件 TestActivity.this.registerReceiver(smsReceiver,filter); }
// 接触广播事件
Publicvoid onClick(Viewv) { TextActicity.this.unregisterReceiver(smsReceiver); }
PublicclassSMSReceiverextendsBroadcastReceiver { @override Publicvoid onReceive(Contextcontext, Intentintent){ System.out,println(&receivemessage&);
// 对接受的短消息进行处理 // 接受 Intent 对象中的数据 Bundlebundle=Intent.getExtras(); // 在 Bundle 对象当中有一个属性名为 pdus, 这个属性的值是一个 Object 数组 Object[]myObjects=(Object[]) bundle.get(&pdus&);
// 创建一个 SmsMessage 类型的数组 SmsMessage[]message=newSmsMessage(myObjects.length); System.out,println(message.length); For(inti=0;i&myObjects.i++) { // 使用 Object 数组当中的对象创建 SmsMessage 对象 Message[i]= SmsMessage.createFromPdu((byte[])myObjects[i]); System.out,println(message[i].getDisplayMessageBody()); }
在 AndroidManifest.xml 中进行注册 (不论应用程序的开启或关闭)
&receiverandroid:name=&.TestReceiver&& &intent-filter& &actionandroid:name=&android,intent.action.PICK&& &/intent-filter& &receiver&
6.Android 内置的 BroadcastActions
十七 十七 十七 十七 . . . .WIFI WIFI WIFI WIFI的操作 的操作 的操作 的操作
1. 什么是 WIFI WIFI 就是一种无线联网的技术 , 则又称为&热点& 2. 获取 WIFI 网卡的状态
0--& 正在关闭 1--& 关闭状态 2--& 正在打开 3--& 网卡可用 4--& 位置状态
3. 操作 WIFI 所需要的权限
4. 改变 WIFI 网卡的状态
例 : 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
Public void onClick(View v ) {
WifiManager wifiManager =
(WifiManager)WifiActivity.this.getSystemService(Serivce.WIFI_SERVICE);
wifiManager.setWifiEnabled(true); // 打开 WIfi 网卡 false 关闭
System.out.println(&wifi state ---&& + wifiManager.getWifiState());
Toast.makeText(WifuActivity.this , & 当 前 的 WIFI 网 卡 状 态 为 & +
wifiManager.getWifiState());
十八 十八 十八 十八 . . . .Scoket Scoket Scoket Scoket编程 编程 编程 编程
1. 什么是 Socket
Socket 英文意为&插座&
所谓 Scoket 通常也称作&套接字&,用于描述 IP 地址和端口,是一个通信链的句柄
应用程序通常通过&套接字&向网络发出请求或者应答网络请求
2.Socket 基本通信模型
3. 使用基于 TCP 协议的 Socket
ServerSocketActivity 代码 例 : 1 . 声明控件对象(略) 2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
Public void onClick(View v) {
New ServerThread().start();
// TCPserver
Class ServerThread extends Thread {
Public void run () {
// 声明一个 serverSocket 对象
ServerSocket serverSocket =
// 创建 serverSocket 对象并在 4567 端口监听
serverSocket = new ServerSocket(4567);
// 调用 serverSocket 的 accept 方法,接受客户端所发送的请求
Socket socket = serverSocket.accept(); // 阻塞函数
// 从 socket 当中得到 inputstream 对象
InputStream inputStream = socket.getInputStream();
Byte buffer [] new bute [1024 * 4];
Int temp = 0 ;
// 从 inputStream 当中读取客户端所发送的数据
While ((temp = inputStream.read(buffer)) != -1) {
System.out,println(new String(buffer , 0 ,temp));
} catch (Execption e) {
e.printStackTrace();
} finally {
serverSocket.close();
} catch (IOExecption e) {
e.printStackTrace();
TCPClient 代码 例 :
Public static void main (String [] args) {
// 创建一个 Socket 对象,指定服务器端的 ip 地址和端口号
Socket socket = new Socket(&192.168.1.1& , 4567);
// 使用 InputStream 读取硬盘上的文件
InputStream inputStream = new FileInputStream(&F://file/words.txt&);
// 从 Socket 上得到 outputStream
outputStream outputStream = socket.getOutputStream();
Byte buffer [] = new byte[4*1024];
Int temp = 0;
// 将 inputStream 的数据取出并写入到 outputStream
While ((temp = inputStream.read(buffer)) != -1) {
outputStream.write(buffer , 0 ,temp);
outpurStream.flush();
} catch (Execption e) {
e.printStackTrace();
// UDPServer
Class ServerThread extends Thread {
Public void run () {
// 创建一个 DatagramSocket 对象,并制定监听端口号
DatagramSocket socket = new DatagramSocket(4567);
Byte data [] = new byte [1024];
// 创建一个空的 DatagramPacket 对象
DatagramPacket packet = new DatagramPacket (data , data.length);
// 使用 receive 方法接受客户端所发送的数据
Socket.receive(packet); // 阻塞方法
String result = new String(packet.getData() , packet.getOffset() ,
packet.getLength()); // 设置数据偏移量 , 得到该次数据的长度
System.out.println(&result--&& + result);
} catch (Execption e) {
e.printStackTrace();
// UDPClient
Public static void main (String [] args) {
// 创建一个 DatagramSocket 对象,并制定监听端口号
DatagramSocket socket = new DatagramSocket(4567);
InetAddress serverAddress = InetAddress.getByName(&192.168.1.1&);
String str = &hello&;
Byte data [] = str.getBytes();
DatagramPacket packet = new DatagramPacket(data , data.length ,
serverAddress , 4567);
Socket.send(packet);
} catch (Execption e) {
e.printStackTrace();
4 . 使用基于 UDP 协议的 Socket
十九 十九 十九 十九 . . . .Service Service Service Service初步 初步 初步 初步
1 . Service 是什么
是一个应用程序组件
没有图形化界面
通常处理一些耗时较长的操作
可以是使用 service 更新 ContnetProvider.发送 intnet 以及启动系统的通知等等
2 . Service 不是什么
不是一个单独的进程
不是一个线程
3 . Service 生命周期
4 . 启动和停止 Service 的方法
服务 例 : public class FirstService extends Service {
Public IBinder onBind(Intent intent) {
System.out.println(&Service onBind&);
Public void onCreate() {
super.onCreate();
System.out.println(&Service onCreate&);
// 启动服务时方法
Public int onStartCommand(Intent intent , int flage , int startId) {
System.out.println(&flags --&& + flags);
System.out.println(&startId --& & + startId);
System.out.println(&service onStartCommand&);
Return START_NOT_STICKY;
Public void onDestroy() {
System.out.println(&Service onDestroy&);
super.onDestroy();
在 AndroidMnaifest.xml 中注册服务 : &service android:name=&.FirstService&&&/service&
在 Activity 中调用 Service 例: 1 . 声明控件对象(略)
2 . 获得控件对象(略)
3 . 绑定事件(略)
4 . 创建监听器对象
// 启动服务
Public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Activity.this , FirstService.class);
startService(intent);
// 停止服务
Public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(Activity.this , FirstService.class);
stopService(intent);
二十 二十 二十 二十 . . . . 项目 项目 项目 项目
嵌到我的页面
<input type="text" readonly="true" value="">
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
移动开发下载排行

我要回帖

更多关于 java thread 传入参数 的文章

 

随机推荐