一.四大组件:java
Android四大组件分别为activity、service、content provider、broadcast receiver。android
1、Android四大组件详解git
一、activityweb
(1)一个Activity一般就是一个单独的屏幕(窗口)。sql
(2)Activity之间经过Intent进行通讯。数据库
(3)android应用中每个Activity都必需要在AndroidManifest.xml配置文件中声明,不然系统将不识别也不执行该Activity。数组
二、service性能优化
(1)service用于在后台完成用户指定的操做。service分为两种:网络
(a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。
(b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。
(2)startService()与bindService()区别:
(a)started service(启动服务)是由其余组件调用startService()方法启动的,这致使服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,而且能够在后台无限期运行,即便启动服务的组件已经被销毁。所以,服务须要在完成任务后调用stopSelf()方法中止,或者由其余组件调用stopService()方法中止。
(b)使用bindService()方法启用服务,调用者与服务绑定在了一块儿,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特色。
(3)开发人员须要在应用程序配置文件中声明所有的service,使用<service></service>标签。
(4)Service一般位于后台运行,它通常不须要与用户交互,所以Service组件没有图形用户界面。Service组件须要继承Service基类。Service组件一般用于为其余组件提供后台服务或监控其余组件的运行状态。
三、content provider
(1)android平台提供了Content Provider使一个应用程序的指定数据集提供给其余应用程序。其余应用能够经过ContentResolver类从该内容提供者中获取或存入数据。
(2)只有须要在多个应用程序间共享数据是才须要内容提供者。例如,通信录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。
(3)ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对全部应用程序可见。这是不一样应用程序间共享数据的惟一方式,由于android没有提供全部应用共同访问的公共存储区。
(4)开发人员不会直接使用ContentProvider类的对象,大多数是经过ContentResolver对象实现对ContentProvider的操做。
(5)ContentProvider使用URI来惟一标识其数据集,这里的URI以content://做为前缀,表示该数据由ContentProvider来管理。
四、broadcast receiver
(1)你的应用可使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并作出响应。广播接收器没有用户界面。然而,它们能够启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知能够用不少种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。通常来讲是在状态栏上放一个持久的图标,用户能够打开它并获取消息。
(2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。
(3)动态注册广播接收器特色是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担心广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app自己未启动,该app订阅的广播在触发时也会对它起做用。
2、android四大组件总结:
(1)4大组件的注册
4大基本组件都须要注册才能使用,每一个Activity、service、Content Provider都须要在AndroidManifest文件中进行配置。AndroidManifest文件中未进行声明的activity、服务以及内容提供者将不为系统所见,从而也就不可用。而broadcast receiver广播接收者的注册分静态注册(在AndroidManifest文件中进行配置)和经过代码动态建立并以调用Context.registerReceiver()的方式注册至系统。须要注意的是在AndroidManifest文件中进行配置的广播接收者会随系统的启动而一直处于活跃状态,只要接收到感兴趣的广播就会触发(即便程序未运行)。
(2)4大组件的激活
内容提供者的激活:当接收到ContentResolver发出的请求后,内容提供者被激活。而其它三种组件activity、服务和广播接收器被一种叫作intent的异步消息所激活。
(3)4大组件的关闭
内容提供者仅在响应ContentResolver提出请求的时候激活。而一个广播接收器仅在响应广播信息的时候激活。因此,没有必要去显式的关闭这些组件。Activity关闭:能够经过调用它的finish()方法来关闭一个activity。服务关闭:对于经过startService()方法启动的服务要调用Context.stopService()方法关闭服务,使用bindService()方法启动的服务要调用Contex.unbindService()方法关闭服务。
(4)android中的任务(activity栈)
(a)任务其实就是activity的栈,它由一个或多个Activity组成,共同完成一个完整的用户体验。栈底的是启动整个任务的Activity,栈顶的是当前运行的用户能够交互的Activity,当一个activity启动另一个的时候,新的activity就被压入栈,并成为当前运行的activity。而前一个activity仍保持在栈之中。当用户按下BACK键的时候,当前activity出栈,而前一个恢复为当前运行的activity。栈中保存的实际上是对象,栈中的Activity永远不会重排,只会压入或弹出。
(b)任务中的全部activity是做为一个总体进行移动的。整个的任务(即activity栈)能够移到前台,或退至后台。
(c)Android系统是一个多任务(Multi-Task)的操做系统,能够在用手机听音乐的同时,也执行其余多个程序。每多执行一个应用程序,就会多耗费一些系统内存,当同时执行的程序过多,或是关闭的程序没有正确释放掉内存,系统就会以为愈来愈慢,甚至不稳定。为了解决这个问题,Android引入了一个新的机制,即生命周期(Life Cycle)。
二.六大布局:
Android六大界面布局方式:
声明Android程序布局有两种方式:
1) 使用XML文件描述界面布局;
2) 在Java代码中经过调用方法进行控制。
咱们既可使用任何一种声明界面布局的方式,也能够同时使用两种方式。
使用XML文件声明有如下3个特色:
- 1) 将程序的表现层和控制层分离;
- 2) 在后期修改用户界面时,无须更改程序的源程序;
- 3) 可经过WYSIWYG可视化工具直接看到所设计的用户界面,有利于加快界面设计的过程。
建议尽可能采用XML文件声明界面元素布局。在程序运行时动态添加界面布局会大大下降应用响应速度,但依然能够在必要时动态改变屏幕内容。
六大界面布局方式包括: 线性布局(LinearLayout)、框架布局(FrameLayout)、表格布局(TableLayout)、相对布局(RelativeLayout)、绝对布局(AbsoluteLayout)和网格布局(GridLayout) 。
1. LinearLayout线性布局
LinearLayout容器中的组件一个挨一个排列,经过控制android:orientation属性,可控制各组件是横向排列仍是纵向排列。
LinearLayout的经常使用XML属性及相关方法
XML属性 |
相关方法 |
说明 |
android:gravity |
setGravity(int) |
设置布局管理器内组件的对齐方式 |
android:orientation |
setOrientation(int) |
设置布局管理器内组件的排列方式,能够设置为horizontal、vertical两个值之一 |
其中,gravity属性支持top, left, right, center_vertical, fill_vertical, center_horizontal, fill_horizontal, center, fill, clip_vertical, clip_horizontal。也能够同时指定多种对齐方式的组合。
LinearLayout子元素支持的经常使用XML属性及方法
XML属性 |
说明 |
android:layout_gravity |
指定该子元素在LinearLayout中的对齐方式 |
android:layout_weight |
指定子元素在LinearLayout中所占的权重 |
2. TableLayout表格布局
TableLayout继承自Linearout,本质上仍然是线性布局管理器。表格布局采用行、列的形式来管理UI组件,并不须要明确地声明包含多少行、多少列,而是经过添加TableRow、其余组件来控制表格的行数和列数。
每向TableLayout中添加一个TableRow就表明一行;
每向TableRow中添加一个一个子组件就表示一列;
若是直接向TableLayout添加组件,那么该组件将直接占用一行;
在表格布局中,能够为单元格设置以下三种行为方式:
- Shrinkable:该列的全部单元格的宽度能够被收缩,以保证该表格能适应父容器的宽度;
- Strentchable:该列全部单元格的宽度能够被拉伸,以保证组件能彻底填满表格空余空间;
- Collapsed:若是该列被设置为Collapsed,那么该列的全部单元格会被隐藏;
TableLayout的经常使用XML属性及方法
XML属性 |
相关方法 |
说明 |
android:collapseColumns |
setColumns(int, boolean) |
设置须要被隐藏的列的序号,多个序号间用逗号分隔 |
android:shrinkColumns |
setShrinkAllColumns(boolean) |
设置须要被收缩的列的序号 |
android:stretchColumns |
setStretchAllColumns(boolean) |
设置容许被拉伸的列的序号 |
3. FrameLayout帧布局
FrameLayout直接继承自ViewGroup组件。帧布局为每一个加入其中的组件建立一个空白的区域(称为一帧),每一个子组件占据一帧,这些帧会根据gravity属性执行自动对齐。
FrameLayout的经常使用XM了属性及方法
XML属性 |
相关方法 |
说明 |
android:foreground |
setForeground(Drawable) |
设置该帧布局容器的前景图像 |
android:foregroundGravity |
setForeGroundGraity(int) |
定义绘制前景图像的gravity属性 |
4. RelativeLayout相对布局
RelativeLayout的XML属性及相关方法说明
XML属性 |
相关方法 |
说明 |
android:gravity |
setGravity(int) |
|
android:ignoreGravity |
setIgnoreGravity(int) |
设置哪一个组件不受gravity属性的影响 |
为了控制该布局容器的各子组件的布局分布,RelativeLayout提供了一个内部类:RelativeLayout.LayoutParams。
RelativeLayout.LayoutParams里只能设为boolean的XML属性
XML属性 |
说明 |
android:layout_centerHorizontal |
设置该子组件是否位于布局容器的水平居中 |
android:layout_centerVertical |
|
android:layout_centerParent |
|
android:layout_alignParentBottom |
|
android:layout_alignParentLeft |
|
android:layout_alignParentRight |
|
android:layout_alignParentTop |
RelativeLayout.LayoutParams里属性值为其余UI组件ID的XML属性
XML属性 |
说明 |
android:layout_toRightOf |
控制该子组件位于给出ID组件的右侧 |
android:layout_toLeftOf |
|
android:layout_above |
|
android:layout_below |
|
android:layout_alignTop |
|
android:layout_alignBottom |
|
android:layout_alignRight |
|
android:layout_alignLeft |
5. Android 4.0新增的网格布局GridLayout
GridLayout是Android4.0增长的网格布局控件,与以前的TableLayout有些类似,它把整个容器划分为rows × columns个网格,每一个网格能够放置一个组件。性能及功能都要比tablelayout好,好比GridLayout布局中的单元格能够跨越多行,而tablelayout则不行,此外,其渲染速度也比tablelayout要快。
GridLayout提供了setRowCount(int)和setColumnCount(int)方法来控制该网格的行和列的数量。
GridLayout经常使用的XML属性和方法说明
XML属性 |
相关方法 |
说明 |
android:alignmentMode |
setAlignmentMode(int) |
设置该布局管理器采用的对齐模式 |
android:columnCount |
setColumnCount(int) |
设置该网格的列数量 |
android:columnOrderPreserved |
setColumnOrderPreserved(boolean) |
设置该网格容器是否保留序列号 |
android:roeCount |
setRowCount(int) |
设置该网格的行数量 |
android:rowOrderPreserved |
setRowOrderPreserved(boolean) |
设置该网格容器是否保留行序号 |
android:useDefaultMargins |
setUseDefaultMargins(boolean) |
设置该布局管理器是否使用默认的页边距 |
为了控制GridLayout布局容器中各子组件的布局分布,GridLayout提供了一个内部类:GridLayout.LayoutParams,来控制Gridlayout布局容器中子组件的布局分布。
GridLayout.LayoutParams经常使用的XML属性和方法说明
XML属性 |
说明 |
android:layout_column |
设置该组件在GridLayout的第几列 |
android:layout_columnSpan |
设置该子组件在GridLayout横向上跨几列 |
android:layout_gravity |
设置该子组件采用何种方式占据该网格的空间 |
android:layout_row |
设置该子组件在GridLayout的第几行 |
android:layout_rowSpan |
设置该子组件在GridLayout纵向上跨几行 |
5. AbsoluteLayout绝对布局
即Android不提供任何布局控制,而是由开发人员本身经过X坐标、Y坐标来控制组件的位置。每一个组件均可指定以下两个XML属性:
绝对布局已通过时,不该使用或少使用。
界面布局类型的选择和性能优化
首先得明确,界面布局类型的嵌套越多越深越复杂,会使布局实例化变慢,使Activity的展开时间延长。建议尽可能减小布局嵌套,尽可能减小建立View对象的数量。
1 . 减小布局层次,可考虑用RelativeLayout来代替LinearLayout。经过Relative的相对其余元素的位置来布局,可减小块状嵌套;
2 . 另外一种减小布局层次的技巧是使用 <merge />
标签来合并布局;
3 . 重用布局。Android支持在XML中使用 <include />
标签, <include />
经过指定android:layout属性来指定要包含的另外一个XML布局。
如:
<include android:id="@+id/id1" android:layout="@layout/mylayout">
<include android:id="@+id/id2" android:layout="@layout/mylayout">
<include android:id="@+id/id3" android:layout="@layout/mylayout">
三.五大存储:
在Android中,可供选择的存储方式有SharedPreferences、文件存储、SQLite数据库方式、内容提供器(Content provider)和网络。
一.SharedPreferences方式
Android提供用来存储一些简单的配置信息的一种机制,例如,一些默认欢迎语、登陆的用户名和密码等。其以键值对的方式存储,
使得咱们能够很方便的读取和存入.
1)程序要实现的功能:
咱们在Name文本框中输入wangwu,在Password文本框中输入123456,而后退出这个应用。咱们在应用程序列表中找到这个应用,从新启动,能够看到其使用了前面输入的Name和Password
2)实现的代码
布局
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SharedPreferences demo"
- />
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="name"
- >
- </TextView>
-
- <EditText
- android:id="@+id/name"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text=""
- >
- </EditText>
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="password"
- >
- </TextView>
-
- <EditText
- android:id="@+id/password"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:password="true"
- android:text=""
- >
- </EditText>
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SharedPreferences demo"
- />
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="name"
- >
- </TextView>
-
- <EditText
- android:id="@+id/name"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text=""
- >
- </EditText>
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="password"
- >
- </TextView>
-
- <EditText
- android:id="@+id/password"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:password="true"
- android:text=""
- >
- </EditText>
- </LinearLayout>
主要实现代码
- package com.demo;
-
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.widget.EditText;
-
- public class SharedPreferencesDemo extends Activity {
-
- public static final String SETTING_INFOS = "SETTING_Infos";
- public static final String NAME = "NAME";
- public static final String PASSWORD = "PASSWORD";
- private EditText field_name; //接收用户名的组件
- private EditText filed_pass; //接收密码的组件
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- //Find VIew
- field_name = (EditText) findViewById(R.id.name); //首先获取用来输入用户名的组件
- filed_pass = (EditText) findViewById(R.id.password); //同时也须要获取输入密码的组件
-
- // Restore preferences
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //获取一个SharedPreferences对象
- String name = settings.getString(NAME, ""); //取出保存的NAME
- String password = settings.getString(PASSWORD, ""); //取出保存的PASSWORD
-
- //Set value
- field_name.setText(name); //将取出来的用户名赋予field_name
- filed_pass.setText(password); //将取出来的密码赋予filed_pass
- }
-
- @Override
- protected void onStop(){
- super.onStop();
-
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //首先获取一个SharedPreferences对象
- settings.edit()
- .putString(NAME, field_name.getText().toString())
- .putString(PASSWORD, filed_pass.getText().toString())
- .commit();
- } //将用户名和密码保存进去
-
- }
- package com.demo;
-
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.widget.EditText;
-
- public class SharedPreferencesDemo extends Activity {
-
- public static final String SETTING_INFOS = "SETTING_Infos";
- public static final String NAME = "NAME";
- public static final String PASSWORD = "PASSWORD";
- private EditText field_name; //接收用户名的组件
- private EditText filed_pass; //接收密码的组件
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- //Find VIew
- field_name = (EditText) findViewById(R.id.name); //首先获取用来输入用户名的组件
- filed_pass = (EditText) findViewById(R.id.password); //同时也须要获取输入密码的组件
-
- // Restore preferences
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //获取一个SharedPreferences对象
- String name = settings.getString(NAME, ""); //取出保存的NAME
- String password = settings.getString(PASSWORD, ""); //取出保存的PASSWORD
-
- //Set value
- field_name.setText(name); //将取出来的用户名赋予field_name
- filed_pass.setText(password); //将取出来的密码赋予filed_pass
- }
-
- @Override
- protected void onStop(){
- super.onStop();
-
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //首先获取一个SharedPreferences对象
- settings.edit()
- .putString(NAME, field_name.getText().toString())
- .putString(PASSWORD, filed_pass.getText().toString())
- .commit();
- } //将用户名和密码保存进去
-
- }
SharedPreferences保存到哪里去了?
SharedPreferences是以XML的格式以文件的方式自动保存的,在DDMS中的File Explorer中展开到/data/data/<package
name>/shared_prefs下,以上面这个为例,能够看到一个叫作SETTING_Infos.xml的文件
注意:Preferences只能在同一个包内使用,不能在不一样的包之间使用。
二.文件存储方式
在Android中,其提供了openFileInput 和 openFileOuput 方法读取设备上的文件,下面看个例子代码,具体以下所示:
String FILE_NAME = "tempfile.tmp"; //肯定要操做文件的文件名
FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); //初始化
FileInputStream fis = openFileInput(FILE_NAME); //建立写入流
上述代码中两个方法只支持读取该应用目录下的文件,读取非其自身目录下的文件将会抛出异常。须要提醒的是,若是调用
FileOutputStream 时指定的文件不存在,Android 会自动建立它。另外,在默认状况下,写入的时候会覆盖原文件内容,若是想把
新写入的内容附加到原文件内容后,则能够指定其模式为Context.MODE_APPEND。
三.SQLite数据库方式
SQLite是Android所带的一个标准的数据库,它支持SQL语句,它是一个轻量级的嵌入式数据库。
1)实现的功能
在这个例子里边,咱们在程序的主界面有一些按钮,经过这些按钮能够对数据库进行标准的增、删、改、查。
2)实现代码
所用到的字符文件
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="app_name">SQLite数据库操做实例</string>
- <string name="button1">创建数据库表</string>
- <string name="button2">删除数据库表</string>
- <string name="button3">插入两条记录</string>
- <string name="button4">删除一条记录</string>
- <string name="button5">查看数据库表</string>
- </resources>
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="app_name">SQLite数据库操做实例</string>
- <string name="button1">创建数据库表</string>
- <string name="button2">删除数据库表</string>
- <string name="button3">插入两条记录</string>
- <string name="button4">删除一条记录</string>
- <string name="button5">查看数据库表</string>
- </resources>
布局代码
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- />
- <Button
- android:text="@string/button1"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button2"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button3"
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button4"
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button5"
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
-
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- />
- <Button
- android:text="@string/button1"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button2"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button3"
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button4"
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button5"
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
-
- </LinearLayout>
主要代码
- package com.sqlite;
-
- import android.app.Activity;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.SQLException;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- /*
- * 什么是SQLiteDatabase?
- * 一个SQLiteDatabase的实例表明了一个SQLite的数据库,经过SQLiteDatabase实例的一些方法,咱们能够执行SQL语句,
- * 对数据库进行增、删、查、改的操做。须要注意的是,数据库对于一个应用来讲是私有的,而且在一个应用当中,数据库的名字也是唯一的。
- */
-
- /*
- * 什么是SQLiteOpenHelper ?
- * 这个类主要生成一个数据库,并对数据库的版本进行管理。
- * 当在程序当中调用这个类的方法getWritableDatabase()或者getReadableDatabase()方法的时候,若是当时没有数据,那么Android系统就会自动生成一个数据库。
- * SQLiteOpenHelper 是一个抽象类,咱们一般须要继承它,而且实现里边的3个函数,
- * onCreate(SQLiteDatabase):在数据库第一次生成的时候会调用这个方法,通常咱们在这个方法里边生成数据库表。
- * onUpgrade(SQLiteDatabase, int, int):当数据库须要升级的时候,Android系统会主动的调用这个方法。通常咱们在这个方法里边删除数据表,并创建新的数据表,固然是否还须要作其余的操做,彻底取决于应用的需求。
- * onOpen(SQLiteDatabase):这是当打开数据库时的回调函数,通常也不会用到。
- */
-
- public class SQLiteDemo extends Activity {
-
- OnClickListener listener1 = null;
- OnClickListener listener2 = null;
- OnClickListener listener3 = null;
- OnClickListener listener4 = null;
- OnClickListener listener5 = null;
-
- Button button1;
- Button button2;
- Button button3;
- Button button4;
- Button button5;
-
- DatabaseHelper mOpenHelper;
-
- private static final String DATABASE_NAME = "dbForTest.db";
- private static final int DATABASE_VERSION = 1;
- private static final String TABLE_NAME = "diary";
- private static final String TITLE = "title";
- private static final String BODY = "body";
-
- //创建一个内部类,主要生成一个数据库
- private static class DatabaseHelper extends SQLiteOpenHelper {
-
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- //在数据库第一次生成的时候会调用这个方法,通常咱们在这个方法里边生成数据库表。
- @Override
- public void onCreate(SQLiteDatabase db) {
-
- String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE
- + " text not null, " + BODY + " text not null " + ");";
- Log.i("haiyang:createDB=", sql);
- db.execSQL(sql);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- prepareListener();
- initLayout();
- mOpenHelper = new DatabaseHelper(this);
-
- }
-
- private void initLayout() {
- button1 = (Button) findViewById(R.id.button1);
- button1.setOnClickListener(listener1);
-
- button2 = (Button) findViewById(R.id.button2);
- button2.setOnClickListener(listener2);
-
- button3 = (Button) findViewById(R.id.button3);
- button3.setOnClickListener(listener3);
-
- button4 = (Button) findViewById(R.id.button4);
- button4.setOnClickListener(listener4);
-
- button5 = (Button) findViewById(R.id.button5);
- button5.setOnClickListener(listener5);
-
- }
-
- private void prepareListener() {
- listener1 = new OnClickListener() {
- public void onClick(View v) {
- CreateTable();
- }
- };
- listener2 = new OnClickListener() {
- public void onClick(View v) {
- dropTable();
- }
- };
- listener3 = new OnClickListener() {
- public void onClick(View v) {
- insertItem();
- }
- };
- listener4 = new OnClickListener() {
- public void onClick(View v) {
- deleteItem();
- }
- };
- listener5 = new OnClickListener() {
- public void onClick(View v) {
- showItems();
- }
- };
- }
-
- /*
- * 从新创建数据表
- */
- private void CreateTable() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE
- + " text not null, " + BODY + " text not null " + ");";
- Log.i("haiyang:createDB=", sql);
-
- try {
- db.execSQL("DROP TABLE IF EXISTS diary");
- db.execSQL(sql);
- setTitle("数据表成功重建");
- } catch (SQLException e) {
- setTitle("数据表重建错误");
- }
- }
-
- /*
- * 删除数据表
- */
- private void dropTable() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "drop table " + TABLE_NAME;
- try {
- db.execSQL(sql);
- setTitle("数据表成功删除:" + sql);
- } catch (SQLException e) {
- setTitle("数据表删除错误");
- }
- }
-
- /*
- * 插入两条数据
- */
- private void insertItem() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('haiyang', 'android的发展真是迅速啊');";
- String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('icesky', 'android的发展真是迅速啊');";
- try {
- // Log.i()会将参数内容打印到日志当中,而且打印级别是Info级别
- // Android支持5种打印级别,分别是Verbose、Debug、Info、Warning、Error,固然咱们在程序当中通常用到的是Info级别
- Log.i("haiyang:sql1=", sql1);
- Log.i("haiyang:sql2=", sql2);
- db.execSQL(sql1);
- db.execSQL(sql2);
- setTitle("插入两条数据成功");
- } catch (SQLException e) {
- setTitle("插入两条数据失败");
- }
- }
-
- /*
- * 删除其中的一条数据
- */
- private void deleteItem() {
- try {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- //第一个参数是数据库表名,在这里是TABLE_NAME,也就是diary。
- //第二个参数,至关于SQL语句当中的where部分,也就是描述了删除的条件。
- //若是在第二个参数当中有“?”符号,那么第三个参数中的字符串会依次替换在第二个参数当中出现的“?”符号。
- db.delete(TABLE_NAME, " title = 'haiyang'", null);
- setTitle("删除title为haiyang的一条记录");
- } catch (SQLException e) {
-
- }
-
- }
-
- /*
- * 在屏幕的title区域显示当前数据表当中的数据的条数。
- */
- /*
- * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)语句将查询到的数据放到一个Cursor 当中。
- 这个Cursor里边封装了这个数据表TABLE_NAME当中的全部条列。
- query()方法至关的有用,在这里咱们简单地讲一下。
- 第一个参数是数据库里边表的名字,好比在咱们这个例子,表的名字就是TABLE_NAME,也就是"diary"。
- 第二个字段是咱们想要返回数据包含的列的信息。在这个例子当中咱们想要获得的列有title、body。咱们把这两个列的名字放到字符串数组里边来。
- 第三个参数为selection,至关于SQL语句的where部分,若是想返回全部的数据,那么就直接置为null。
- 第四个参数为selectionArgs。在selection部分,你有可能用到“?”,那么在selectionArgs定义的字符串会代替selection中的“?”。
- 第五个参数为groupBy。定义查询出来的数据是否分组,若是为null则说明不用分组。
- 第六个参数为having ,至关于SQL语句当中的having部分。
- 第七个参数为orderBy,来描述咱们指望的返回值是否须要排序,若是设置为null则说明不须要排序。
- */
-
- private void showItems() {
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- String col[] = { TITLE, BODY };
- //查询数据
- Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);
- Integer num = cur.getCount();
- setTitle(Integer.toString(num) + " 条记录");
- }
- }
- package com.sqlite;
-
- import android.app.Activity;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.SQLException;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- /*
- * 什么是SQLiteDatabase?
- * 一个SQLiteDatabase的实例表明了一个SQLite的数据库,经过SQLiteDatabase实例的一些方法,咱们能够执行SQL语句,
- * 对数据库进行增、删、查、改的操做。须要注意的是,数据库对于一个应用来讲是私有的,而且在一个应用当中,数据库的名字也是唯一的。
- */
-
- /*
- * 什么是SQLiteOpenHelper ?
- * 这个类主要生成一个数据库,并对数据库的版本进行管理。
- * 当在程序当中调用这个类的方法getWritableDatabase()或者getReadableDatabase()方法的时候,若是当时没有数据,那么Android系统就会自动生成一个数据库。
- * SQLiteOpenHelper 是一个抽象类,咱们一般须要继承它,而且实现里边的3个函数,
- * onCreate(SQLiteDatabase):在数据库第一次生成的时候会调用这个方法,通常咱们在这个方法里边生成数据库表。
- * onUpgrade(SQLiteDatabase, int, int):当数据库须要升级的时候,Android系统会主动的调用这个方法。通常咱们在这个方法里边删除数据表,并创建新的数据表,固然是否还须要作其余的操做,彻底取决于应用的需求。
- * onOpen(SQLiteDatabase):这是当打开数据库时的回调函数,通常也不会用到。
- */
-
- public class SQLiteDemo extends Activity {
-
- OnClickListener listener1 = null;
- OnClickListener listener2 = null;
- OnClickListener listener3 = null;
- OnClickListener listener4 = null;
- OnClickListener listener5 = null;
-
- Button button1;
- Button button2;
- Button button3;
- Button button4;
- Button button5;
-
- DatabaseHelper mOpenHelper;
-
- private static final String DATABASE_NAME = "dbForTest.db";
- private static final int DATABASE_VERSION = 1;
- private static final String TABLE_NAME = "diary";
- private static final String TITLE = "title";
- private static final String BODY = "body";
-
- //创建一个内部类,主要生成一个数据库
- private static class DatabaseHelper extends SQLiteOpenHelper {
-
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- //在数据库第一次生成的时候会调用这个方法,通常咱们在这个方法里边生成数据库表。
- @Override
- public void onCreate(SQLiteDatabase db) {
-
- String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE
- + " text not null, " + BODY + " text not null " + ");";
- Log.i("haiyang:createDB=", sql);
- db.execSQL(sql);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- prepareListener();
- initLayout();
- mOpenHelper = new DatabaseHelper(this);
-
- }
-
- private void initLayout() {
- button1 = (Button) findViewById(R.id.button1);
- button1.setOnClickListener(listener1);
-
- button2 = (Button) findViewById(R.id.button2);
- button2.setOnClickListener(listener2);
-
- button3 = (Button) findViewById(R.id.button3);
- button3.setOnClickListener(listener3);
-
- button4 = (Button) findViewById(R.id.button4);
- button4.setOnClickListener(listener4);
-
- button5 = (Button) findViewById(R.id.button5);
- button5.setOnClickListener(listener5);
-
- }
-
- private void prepareListener() {
- listener1 = new OnClickListener() {
- public void onClick(View v) {
- CreateTable();
- }
- };
- listener2 = new OnClickListener() {
- public void onClick(View v) {
- dropTable();
- }
- };
- listener3 = new OnClickListener() {
- public void onClick(View v) {
- insertItem();
- }
- };
- listener4 = new OnClickListener() {
- public void onClick(View v) {
- deleteItem();
- }
- };
- listener5 = new OnClickListener() {
- public void onClick(View v) {
- showItems();
- }
- };
- }
-
- /*
- * 从新创建数据表
- */
- private void CreateTable() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE
- + " text not null, " + BODY + " text not null " + ");";
- Log.i("haiyang:createDB=", sql);
-
- try {
- db.execSQL("DROP TABLE IF EXISTS diary");
- db.execSQL(sql);
- setTitle("数据表成功重建");
- } catch (SQLException e) {
- setTitle("数据表重建错误");
- }
- }
-
- /*
- * 删除数据表
- */
- private void dropTable() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "drop table " + TABLE_NAME;
- try {
- db.execSQL(sql);
- setTitle("数据表成功删除:" + sql);
- } catch (SQLException e) {
- setTitle("数据表删除错误");
- }
- }
-
- /*
- * 插入两条数据
- */
- private void insertItem() {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('haiyang', 'android的发展真是迅速啊');";
- String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('icesky', 'android的发展真是迅速啊');";
- try {
- // Log.i()会将参数内容打印到日志当中,而且打印级别是Info级别
- // Android支持5种打印级别,分别是Verbose、Debug、Info、Warning、Error,固然咱们在程序当中通常用到的是Info级别
- Log.i("haiyang:sql1=", sql1);
- Log.i("haiyang:sql2=", sql2);
- db.execSQL(sql1);
- db.execSQL(sql2);
- setTitle("插入两条数据成功");
- } catch (SQLException e) {
- setTitle("插入两条数据失败");
- }
- }
-
- /*
- * 删除其中的一条数据
- */
- private void deleteItem() {
- try {
- //mOpenHelper.getWritableDatabase()语句负责获得一个可写的SQLite数据库,若是这个数据库尚未创建,
- //那么mOpenHelper辅助类负责创建这个数据库。若是数据库已经创建,那么直接返回一个可写的数据库。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- //第一个参数是数据库表名,在这里是TABLE_NAME,也就是diary。
- //第二个参数,至关于SQL语句当中的where部分,也就是描述了删除的条件。
- //若是在第二个参数当中有“?”符号,那么第三个参数中的字符串会依次替换在第二个参数当中出现的“?”符号。
- db.delete(TABLE_NAME, " title = 'haiyang'", null);
- setTitle("删除title为haiyang的一条记录");
- } catch (SQLException e) {
-
- }
-
- }
-
- /*
- * 在屏幕的title区域显示当前数据表当中的数据的条数。
- */
- /*
- * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)语句将查询到的数据放到一个Cursor 当中。
- 这个Cursor里边封装了这个数据表TABLE_NAME当中的全部条列。
- query()方法至关的有用,在这里咱们简单地讲一下。
- 第一个参数是数据库里边表的名字,好比在咱们这个例子,表的名字就是TABLE_NAME,也就是"diary"。
- 第二个字段是咱们想要返回数据包含的列的信息。在这个例子当中咱们想要获得的列有title、body。咱们把这两个列的名字放到字符串数组里边来。
- 第三个参数为selection,至关于SQL语句的where部分,若是想返回全部的数据,那么就直接置为null。
- 第四个参数为selectionArgs。在selection部分,你有可能用到“?”,那么在selectionArgs定义的字符串会代替selection中的“?”。
- 第五个参数为groupBy。定义查询出来的数据是否分组,若是为null则说明不用分组。
- 第六个参数为having ,至关于SQL语句当中的having部分。
- 第七个参数为orderBy,来描述咱们指望的返回值是否须要排序,若是设置为null则说明不须要排序。
- */
-
- private void showItems() {
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- String col[] = { TITLE, BODY };
- //查询数据
- Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);
- Integer num = cur.getCount();
- setTitle(Integer.toString(num) + " 条记录");
- }
- }
四.内容提供器(Content provider)方式
在Android的设计“哲学”里是鼓励开发者使用内部类的,这样不但使用方便,并且执行效率也高。
1.什么是ContentProvider
数据在Android当中是私有的,固然这些数据包括文件数据和数据库数据以及一些其余类型的数据。难道两个程序之间就没有办法对于数据进行交换?解决这个问题主要靠ContentProvider。
一个Content Provider类实现了一组标准的方法接口,从而可以让其余的应用保存或读取此Content Provider的各类数据类型。也就是说,一个程序能够经过实现一个Content Provider的抽象接口将本身的数据暴露出去。外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储仍是用文件存储,仍是经过网上得到,这些一切都不重要,重要的是外界能够经过这一套标准及统一的接口和程序里的数据打交道,能够读取程序的数据,也能够删除程序的数据,固然,中间也会涉及一些权限的问题。
下边列举一些较常见的接口,这些接口以下所示。
query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):经过Uri进行查询,返回一个Cursor。
insert(Uri url, ContentValues values):将一组数据插入到Uri 指定的地方。
update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的数据。
delete(Uri url, String where, String[] selectionArgs):删除指定Uri而且符合必定条件的数据。
2.什么是ContentResolver
外界的程序经过ContentResolver接口能够访问ContentProvider提供的数据,在Activity当中经过getContentResolver()能够获得当前应用的ContentResolver实例。
ContentResolver提供的接口和ContentProvider中须要实现的接口对应,主要有如下几个。
query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):经过Uri进行查询,返回一个Cursor。
insert(Uri url, ContentValues values):将一组数据插入到Uri 指定的地方。
update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的数据。
delete(Uri url, String where, String[] selectionArgs):删除指定Uri而且符合必定条件的数据。
3.ContentProvider和ContentResolver中用到的Uri
在ContentProvider和ContentResolver当中用到了Uri的形式一般有两种,一种是指定所有数据,另外一种是指定某个ID的数据。
咱们看下面的例子。
content://contacts/people/ 这个Uri指定的就是所有的联系人数据。
content://contacts/people/1 这个Uri指定的是ID为1的联系人的数据。
在上边两个类中用到的Uri通常由3部分组成。
第一部分是:"content://" 。
第二部分是要得到数据的一个字符串片断。
最后就是ID(若是没有指定ID,那么表示返回所有)。
因为URI一般比较长,并且有时候容易出错,且难以理解。因此,在Android当中定义了一些辅助类,而且定义了一些常量来代替这些长字符串的使用,例以下边的代码:
Contacts.People.CONTENT_URI (联系人的URI)。
1)实现的功能
在这个例子里边,首先在系统的联系人应用当中插入一些联系人信息,而后把这些联系人的名字和电话再显示出来
2)实现方法
- package com.contentProvider;
-
- import android.app.ListActivity;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.provider.Contacts.Phones;
- import android.widget.ListAdapter;
- import android.widget.SimpleCursorAdapter;
-
- public class ContentProviderDemo extends ListActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //getContentResolver()方法获得应用的ContentResolver实例。
- // query(Phones.CONTENT_URI, null, null, null, null)。它是ContentResolver里的方法,负责查询全部联系人,并返回一个Cursor。这个方法参数比较多,每一个参数的具体含义以下。
- //· 第一个参数为Uri,在这个例子里边这个Uri是联系人的Uri。
- //· 第二个参数是一个字符串的数组,数组里边的每个字符串都是数据表中某一列的名字,它指定返回数据表中那些列的值。
- //· 第三个参数至关于SQL语句的where部分,描述哪些值是咱们须要的。
- //· 第四个参数是一个字符串数组,它里边的值依次代替在第三个参数中出现的“?”符号。
- //· 第五个参数指定了排序的方式。
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
- startManagingCursor(c); //让系统来管理生成的Cursor。
- ListAdapter adapter = new SimpleCursorAdapter(
- this,
- android.R.layout.simple_list_item_2,
- c,
- new String[] { Phones.NAME, Phones.NUMBER },
- new int[] { android.R.id.text1, android.R.id.text2 });
- setListAdapter(adapter); //将ListView和SimpleCursorAdapter进行绑定。
- }
-
- }
- package com.contentProvider;
-
- import android.app.ListActivity;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.provider.Contacts.Phones;
- import android.widget.ListAdapter;
- import android.widget.SimpleCursorAdapter;
-
- public class ContentProviderDemo extends ListActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //getContentResolver()方法获得应用的ContentResolver实例。
- // query(Phones.CONTENT_URI, null, null, null, null)。它是ContentResolver里的方法,负责查询全部联系人,并返回一个Cursor。这个方法参数比较多,每一个参数的具体含义以下。
- //· 第一个参数为Uri,在这个例子里边这个Uri是联系人的Uri。
- //· 第二个参数是一个字符串的数组,数组里边的每个字符串都是数据表中某一列的名字,它指定返回数据表中那些列的值。
- //· 第三个参数至关于SQL语句的where部分,描述哪些值是咱们须要的。
- //· 第四个参数是一个字符串数组,它里边的值依次代替在第三个参数中出现的“?”符号。
- //· 第五个参数指定了排序的方式。
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
- startManagingCursor(c); //让系统来管理生成的Cursor。
- ListAdapter adapter = new SimpleCursorAdapter(
- this,
- android.R.layout.simple_list_item_2,
- c,
- new String[] { Phones.NAME, Phones.NUMBER },
- new int[] { android.R.id.text1, android.R.id.text2 });
- setListAdapter(adapter); //将ListView和SimpleCursorAdapter进行绑定。
- }
-
- }
五. 网络存储方式
1.例子介绍
经过邮政编码查询该地区的天气预报,以POST发送的方式发送请求到webservicex.NET站点,访问WebService.webservicex.Net站点上提供查询天气预报的服务,具体信息请参考其WSDL文档,网址为:
http://www.webservicex.net/WeatherForecast.asmx?WSDL。
输入:美国某个城市的邮政编码。
输出:该邮政编码对应城市的天气预报。
2.实现步骤以下
(1)若是须要访问外部网络,则须要在AndroidManifest.xml文件中加入以下代码申请权限许可:
<!-- Permissions -->
<uses-permission Android:name="Android.permission.INTERNET" />
(2)以HTTP POST的方式发送(注意:SERVER_URL并非指WSDL的URL,而是服务自己的URL)。实现的代码以下所示:
private static final String SERVER_URL = "http://www.webservicex.net/WeatherForecast. asmx/GetWeatherByZipCode"; //定义须要获取的内容来源地址
HttpPost request = new HttpPost(SERVER_URL); //根据内容来源地址建立一个Http请求
// 添加一个变量
List <NameValuePair> params = new ArrayList <NameValuePair>();
// 设置一个华盛顿区号
params.add(new BasicNameValuePair("ZipCode", "200120")); //添加必须的参数
request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); //设置参数的编码
try {
HttpResponse httpResponse = new DefaultHttpClient().execute(request); //发送请求并获取反馈
// 解析返回的内容
if(httpResponse.getStatusLine().getStatusCode() != 404)
{
String result = EntityUtils.toString(httpResponse.getEntity());
Log.d(LOG_TAG, result);
}
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
代码解释:
如上代码使用Http从webservicex获取ZipCode为“200120”(美国WASHINGTON D.C)的内容,其返回的内容以下:
<WeatherForecasts xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http: //www.w3.org/2001/XMLSchema-instance" xmlns="http://www.webservicex.net"> <Latitude>38.97571</Latitude> <Longitude>77.02825</Longitude> <AllocationFactor>0.024849</AllocationFactor> <FipsCode>11</FipsCode> <PlaceName>WASHINGTON</PlaceName> <StateCode>DC</StateCode> <Details> <WeatherData> <Day>Saturday, April 25, 2009</Day> <WeatherImage>http://forecast.weather.gov/images/wtf/sct.jpg</WeatherImage> <MaxTemperatureF>88</MaxTemperatureF> <MinTemperatureF>57</MinTemperatureF> <MaxTemperatureC>31</MaxTemperatureC> <MinTemperatureC>14</MinTemperatureC> </WeatherData> <WeatherData> <Day>Sunday, April 26, 2009</Day> <WeatherImage>http://forecast.weather.gov/images/wtf/few.jpg</WeatherImage> <MaxTemperatureF>89</MaxTemperatureF> <MinTemperatureF>60</MinTemperatureF> <MaxTemperatureC>32</MaxTemperatureC> <MinTemperatureC>16</MinTemperatureC> </WeatherData>… </Details> </WeatherForecasts>