Android之四大组件、六大布局、五大存储总结

Android之四大组件、六大布局、五大存储总结

2023年7月15日发(作者:)

Android之四⼤组件、六⼤布局、五⼤存储总结Android之四⼤组件、六⼤布局、五⼤存储

⼀.四⼤组件:四⼤组件分别为activity、service、content provider、broadcast receiver。

⼀、android四⼤组件详解1、activity(1)⼀个Activity通常就是⼀个单独的屏幕(窗⼝)。(2)Activity之间通过Intent进⾏通信。(3)android应⽤中每⼀个Activity都必须要在配置⽂件中声明,否则系统将不识别也不执⾏该Activity。2、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,使⽤标签。(4)Service通常位于后台运⾏,它⼀般不需要与⽤户交互,因此Service组件没有图形⽤户界⾯。Service组件需要继承Service基类。Service组件通常⽤于为其他组件提供后台服务或监控其他组件的运⾏状态。3、content provider(1)android平台提供了Content Provider使⼀个应⽤程序的指定数据集提供给其他应⽤程序。其他应⽤可以通过ContentResolver类从该内容提供者中获取或存⼊数据。(2)只有需要在多个应⽤程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应⽤程序使⽤,且必须存储在⼀个内容提供者中。它的好处是统⼀数据访问⽅式。(3)ContentProvider实现数据共享。ContentProvider⽤于保存和获取数据,并使其对所有应⽤程序可见。这是不同应⽤程序间共享数据的唯⼀⽅式,因为android没有提供所有应⽤共同访问的公共存储区。(4)开发⼈员不会直接使⽤ContentProvider类的对象,⼤多数是通过ContentResolver对象实现对ContentProvider的操作。(5)ContentProvider使⽤URI来唯⼀标识其数据集,这⾥的URI以content://作为前缀,表⽰该数据由ContentProvider来管理。4、broadcast receiver(1)你的应⽤可以使⽤它对外部事件进⾏过滤,只对感兴趣的外部事件(如当电话呼⼊时,或者数据⽹络可⽤时)进⾏接收并做出响应。⼴播接收器没有⽤户界⾯。然⽽,它们可以启动⼀个activity或serice来响应它们收到的信息,或者⽤NotificationManager来通知⽤户。通知可以⽤很多种⽅式来吸引⽤户的注意⼒,例如闪动背灯、震动、播放声⾳等。⼀般来说是在状态栏上放⼀个持久的图标,⽤户可以打开它并获取消息。(2)⼴播接收者的注册有两种⽅法,分别是程序动态注册和AndroidManifest⽂件中进⾏静态注册。(3)动态注册⼴播接收器特点是当⽤来注册的Activity关掉后,⼴播也就失效了。静态注册⽆需担忧⼴播接收器是否被关闭,只要设备是开启状态,⼴播接收器也是打开着的。也就是说哪怕app本⾝未启动,该app订阅的⼴播在触发时也会对它起作⽤。⼆、android四⼤组件总结:(1)4⼤组件的注册4⼤基本组件都需要注册才能使⽤,每个Activity、service、Content Provider都需要在AndroidManifest⽂件中进⾏配置。AndroidManifest⽂件中未进⾏声明的activity、服务以及内容提供者将不为系统所见,从⽽也就不可⽤。⽽broadcast receiver⼴播接收者的注册分静态注册(在AndroidManifest⽂件中进⾏配置)和通过代码动态创建并以调⽤erReceiver()的⽅式注册⾄系统。需要注意的是在AndroidManifest⽂件中进⾏配置的⼴播接收者会随系统的启动⽽⼀直处于活跃状态,只要接收到感兴趣的⼴播就会触发(即使程序未运⾏)。(2)4⼤组件的激活内容提供者的激活:当接收到ContentResolver发出的请求后,内容提供者被激活。⽽其它三种组件activity、服务和⼴播接收器被⼀种叫做intent的异步消息所激活。(3)4⼤组件的关闭内容提供者仅在响应ContentResolver提出请求的时候激活。⽽⼀个⼴播接收器仅在响应⼴播信息的时候激活。所以,没有必要去显式的关闭这些组件。Activity关闭:可以通过调⽤它的finish()⽅法来关闭⼀个activity。服务关闭:对于通过startService()⽅法启动的服务要调⽤rvice()⽅法关闭服务,使⽤bindService()⽅法启动的服务要调⽤Service()⽅法关闭服务。(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:gravityXML属性android:orientationsetGravity(int)相关⽅法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:collapseColumnsandroid:shrinkColumnsandroid:stretchColumns相关⽅法setColumns(int, boolean)setShrinkAllColumns(boolean)setStretchAllColumns(boolean)说明设置需要被隐藏的列的序号,多个序号间⽤逗号分隔设置需要被收缩的列的序号设置允许被拉伸的列的序号3. FrameLayout帧布局FrameLayout直接继承⾃ViewGroup组件。帧布局为每个加⼊其中的组件创建⼀个空⽩的区域(称为⼀帧),每个⼦组件占据⼀帧,这些帧会根据gravity属性执⾏⾃动对齐。FrameLayout的常⽤XM了属性及⽅法XML属性android:foregroundandroid:foregroundGravity相关⽅法setForeground(Drawable)setForeGroundGraity(int)说明设置该帧布局容器的前景图像定义绘制前景图像的gravity属性4. RelativeLayout相对布局RelativeLayout的XML属性及相关⽅法说明XML属性android:gravityandroid:ignoreGravitysetGravity(int)setIgnoreGravity(int)相关⽅法

设置哪个组件不受gravity属性的影响说明为了控制该布局容器的各⼦组件的布局分布,RelativeLayout提供了⼀个内部类:Params。Params⾥只能设为boolean的XML属性XML属性android:layout_centerHorizontal说明设置该⼦组件是否位于布局容器的⽔平居中android:layout_centerVerticalXML属性android:layout_centerParentandroid:layout_alignParentLeftandroid:layout_alignParentTop

说明android:layout_alignParentBottom

android:layout_alignParentRight

Params⾥属性值为其他UI组件ID的XML属性XML属性android:layout_toRightOfandroid:layout_toLeftOfandroid:layout_aboveandroid:layout_belowandroid:layout_alignTop

说明控制该⼦组件位于给出ID组件的右侧android:layout_alignBottom

android:layout_alignRight

android:layout_alignLeft5. Android 4.0新增的⽹格布局GridLayoutGridLayout是Android4.0增加的⽹格布局控件,与之前的TableLayout有些相似,它把整个容器划分为rows × columns个⽹格,每个⽹格可以放置⼀个组件。性能及功能都要⽐tablelayout好,⽐如GridLayout布局中的单元格可以跨越多⾏,⽽tablelayout则不⾏,此外,其渲染速度也⽐tablelayout要快。GridLayout提供了setRowCount(int)和setColumnCount(int)⽅法来控制该⽹格的⾏和列的数量。GridLayout常⽤的XML属性和⽅法说明XML属性android:alignmentModeandroid:columnCountandroid:columnOrderPreservedandroid:roeCountandroid:rowOrderPreservedandroid:useDefaultMarginssetColumnCount(int)setColumnOrderPreserved(boolean)setRowCount(int)setRowOrderPreserved(boolean)setUseDefaultMargins(boolean)相关⽅法setAlignmentMode(int)说明设置该布局管理器采⽤的对齐模式设置该⽹格的列数量设置该⽹格容器是否保留序列号设置该⽹格的⾏数量设置该⽹格容器是否保留⾏序号设置该布局管理器是否使⽤默认的页边距为了控制GridLayout布局容器中各⼦组件的布局分布,GridLayout提供了⼀个内部类:Params,来控制Gridlayout布局容器中⼦组件的布局分布。Params常⽤的XML属性和⽅法说明XML属性android:layout_columnandroid:layout_gravityandroid:layout_rowandroid:layout_rowSpan说明设置该组件在GridLayout的第⼏列设置该⼦组件采⽤何种⽅式占据该⽹格的空间设置该⼦组件在GridLayout的第⼏⾏设置该⼦组件在GridLayout纵向上跨⼏⾏android:layout_columnSpan设置该⼦组件在GridLayout横向上跨⼏列6. AbsoluteLayout绝对布局即Android不提供任何布局控制,⽽是由开发⼈员⾃⼰通过X坐标、Y坐标来控制组件的位置。每个组件都可指定如下两个XML属性:layour_x;layout_y;绝对布局已经过时,不应使⽤或少使⽤。界⾯布局类型的选择和性能优化⾸先得明确,界⾯布局类型的嵌套越多越深越复杂,会使布局实例化变慢,使Activity的展开时间延长。建议尽量减少布局嵌套,尽量减少创建View对象的数量。1 . 减少布局层次,可考虑⽤RelativeLayout来代替LinearLayout。通过Relative的相对其他元素的位置来布局,可减少块状嵌套;2 . 另⼀种减少布局层次的技巧是使⽤

标签来合并布局;3 . 重⽤布局。Android⽀持在XML中使⽤

标签,

通过指定android:layout属性来指定要包含的另⼀个XML布局。如:

三.五⼤存储:

在中,可供选择的存储⽅式有SharedPreferences、⽂件存储、SQLite⽅式、内容提供器(Content provider)和⽹络。⼀.SharedPreferences⽅式 Android提供⽤来存储⼀些简单的配置信息的⼀种机制,例如,⼀些默认欢迎语、登录的⽤户名和密码等。其以键值对的⽅式存储,使得我们可以很⽅便的读取和存⼊. 1)程序要实现的功能: 我们在Name⽂本框中输⼊wangwu,在Password⽂本框中输⼊123456,然后退出这个应⽤。我们在应⽤程序列表中找到这个应⽤,重新启动,可以看到其使⽤了前⾯输⼊的Name和Password 2)实现的代码 布局

1.

2.

3. android:orientation="vertical"

4. android:layout_width="fill_parent"

5. android:layout_height="fill_parent"

6. >

7.

8. android:layout_width="fill_parent"

9. android:layout_height="wrap_content"

10. android:text="SharedPreferences demo"

11. />

12.

13.

14. android:layout_width="fill_parent"

15. android:layout_height="wrap_content"

16. android:text="name"

17. >

18.

19.

20.

21. android:id="@+id/name"

22. android:layout_width="fill_parent"

23. android:layout_height="wrap_content"

24. android:text=""

25. >

26.

27.

28.

29. android:layout_width="fill_parent" 30. android:layout_height="wrap_content"

31. android:text="password"

32. >

33.

34.

35.

36. android:id="@+id/password"

37. android:layout_width="fill_parent"

38. android:layout_height="wrap_content"

39. android:password="true"

40. android:text=""

41. >

42.

43.

主要实现代码

1. package ;

2.

3. import ty;

4. import Preferences;

5. import ;

6. import xt;

7.

8. public class SharedPreferencesDemo extends Activity {

9.

10. public static final String SETTING_INFOS = "SETTING_Infos";

11. public static final String NAME = "NAME";

12. public static final String PASSWORD = "PASSWORD";

13. private EditText field_name; //接收⽤户名的组件

14. private EditText filed_pass; //接收密码的组件

15.

16. @Override

17. public void onCreate(Bundle savedInstanceState) {

18. te(savedInstanceState);

19. setContentView();

20.

21. //Find VIew

22. field_name = (EditText) findViewById(); //⾸先获取⽤来输⼊⽤户名的组件

23. filed_pass = (EditText) findViewById(rd); //同时也需要获取输⼊密码的组件

24.

25. // Restore preferences

26. SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //获取⼀个SharedPreferences对象

27. String name = ing(NAME, ""); //取出保存的NAME

28. String password = ing(PASSWORD, ""); //取出保存的PASSWORD

29.

30. //Set value

31. field_t(name); //将取出来的⽤户名赋予field_name

32. filed_t(password); //将取出来的密码赋予filed_pass

33. }

34.

35. @Override

36. protected void onStop(){

37. ();

38.

39. SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //⾸先获取⼀个SharedPreferences对象 40. ()

41. .putString(NAME, field_t().toString())

42. .putString(PASSWORD, filed_t().toString())

43. .commit();

44. } //将⽤户名和密码保存进去

45.

46. }

SharedPreferences保存到哪⾥去了?

SharedPreferences是以XML的格式以⽂件的⽅式⾃动保存的,在DDMS中的File Explorer中展开到/data/data//shared_prefs下,以上⾯这个为例,可以看到⼀个叫做SETTING_的⽂件 注意:Preferences只能在同⼀个包内使⽤,不能在不同的包之间使⽤。⼆.⽂件存储⽅式 在Android中,其提供了openFileInput 和 openFileOuput ⽅法读取设备上的⽂件,下⾯看个例⼦代码,具体如下所⽰:

String FILE_NAME = ""; //确定要操作⽂件的⽂件名 FileOutputStream fos = openFileOutput(FILE_NAME, _PRIVATE); //初始化 FileInputStream fis = openFileInput(FILE_NAME); //创建写⼊流 上述代码中两个⽅法只⽀持读取该应⽤⽬录下的⽂件,读取⾮其⾃⾝⽬录下的⽂件将会抛出异常。需要提醒的是,如果调⽤FileOutputStream 时指定的⽂件不存在,Android 会⾃动创建它。另外,在默认情况下,写⼊的时候会覆盖原⽂件内容,如果想把新写⼊的内容附加到原⽂件内容后,则可以指定其模式为_APPEND。

三.SQLite数据库⽅式 SQLite是Android所带的⼀个标准的数据库,它⽀持SQL语句,它是⼀个轻量级的嵌⼊式数据库。 1)实现的功能 在这个例⼦⾥边,我们在程序的主界⾯有⼀些按钮,通过这些按钮可以对数据库进⾏标准的增、删、改、查。 2)实现代码 所⽤到的字符⽂件

1.

2.

3. SQLite数据库操作实例

4. 建⽴数据库表

5. 删除数据库表

6. 插⼊两条记录

7. 删除⼀条记录

8. 查看数据库表

9.

布局代码

1.

2.

3. android:orientation="vertical"

4. android:layout_width="fill_parent"

5. android:layout_height="fill_parent"

6. >

7.

8.

9. android:layout_width="fill_parent"

10. android:layout_height="wrap_content"

11. android:text="@string/app_name"

12. />

13.

19.

25.

31.

37.

43.

44.

主要代码

1. package ;

2.

3. import ty;

4. import t;

5. import ;

6. import eption;

7. import Database; 8. import OpenHelper;

9. import ;

10. import ;

11. import ;

12. import kListener;

13. import ;

14.

15. /*

16. * 什么是SQLiteDatabase?

17. * ⼀个SQLiteDatabase的实例代表了⼀个SQLite的数据库,通过SQLiteDatabase实例的⼀些⽅法,我们可以执⾏SQL语句,

18. * 对数据库进⾏增、删、查、改的操作。需要注意的是,数据库对于⼀个应⽤来说是私有的,并且在⼀个应⽤当中,数据库的名字也是惟⼀的。

19. */

20.

21. /*

22. * 什么是SQLiteOpenHelper ?

23. * 这个类主要⽣成⼀个数据库,并对数据库的版本进⾏管理。

24. * 当在程序当中调⽤这个类的⽅法getWritableDatabase()或者getReadableDatabase()⽅法的时候,如果当时没有数据,那么Android系统就会⾃动⽣成⼀个数据库。

25. * SQLiteOpenHelper 是⼀个抽象类,我们通常需要继承它,并且实现⾥边的3个函数,

26. * onCreate(SQLiteDatabase):在数据库第⼀次⽣成的时候会调⽤这个⽅法,⼀般我们在这个⽅法⾥边⽣成数据库表。

27. * onUpgrade(SQLiteDatabase, int, int):当数据库需要升级的时候,Android系统会主动的调⽤这个⽅法。⼀般我们在这个⽅法⾥边删除数据表,并建⽴新的数据表,当然是否还需要做其他的操作,完全取决于应⽤的需求。

28. * onOpen(SQLiteDatabase):这是当打开数据库时的回调函数,⼀般也不会⽤到。

29. */

30.

31. public class SQLiteDemo extends Activity {

32.

33. OnClickListener listener1 = null;

34. OnClickListener listener2 = null;

35. OnClickListener listener3 = null;

36. OnClickListener listener4 = null;

37. OnClickListener listener5 = null;

38.

39. Button button1;

40. Button button2;

41. Button button3;

42. Button button4;

43. Button button5;

44.

45. DatabaseHelper mOpenHelper;

46.

47. private static final String DATABASE_NAME = "";

48. private static final int DATABASE_VERSION = 1;

49. private static final String TABLE_NAME = "diary";

50. private static final String TITLE = "title";

51. private static final String BODY = "body";

52.

53. //建⽴⼀个内部类,主要⽣成⼀个数据库

54. private static class DatabaseHelper extends SQLiteOpenHelper {

55.

56. DatabaseHelper(Context context) {

57. super(context, DATABASE_NAME, null, DATABASE_VERSION);

58. }

59.

60. //在数据库第⼀次⽣成的时候会调⽤这个⽅法,⼀般我们在这个⽅法⾥边⽣成数据库表。

61. @Override

62. public void onCreate(SQLiteDatabase db) {

63.

64. String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE

65. + " text not null, " + BODY + " text not null " + ");";

66. Log.i("haiyang:createDB=", sql);

67. L(sql);

68. }

69.

70. @Override

71. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

72. } 73. }

74.

75. @Override

76. public void onCreate(Bundle savedInstanceState) {

77. te(savedInstanceState);

78. setContentView();

79. prepareListener();

80. initLayout();

81. mOpenHelper = new DatabaseHelper(this);

82.

83. }

84.

85. private void initLayout() {

86. button1 = (Button) findViewById(1);

87. lickListener(listener1);

88.

89. button2 = (Button) findViewById(2);

90. lickListener(listener2);

91.

92. button3 = (Button) findViewById(3);

93. lickListener(listener3);

94.

95. button4 = (Button) findViewById(4);

96. lickListener(listener4);

97.

98. button5 = (Button) findViewById(5);

99. lickListener(listener5);

100.

101. }

102.

103. private void prepareListener() {

104. listener1 = new OnClickListener() {

105. public void onClick(View v) {

106. CreateTable();

107. }

108. };

109. listener2 = new OnClickListener() {

110. public void onClick(View v) {

111. dropTable();

112. }

113. };

114. listener3 = new OnClickListener() {

115. public void onClick(View v) {

116. insertItem();

117. }

118. };

119. listener4 = new OnClickListener() {

120. public void onClick(View v) {

121. deleteItem();

122. }

123. };

124. listener5 = new OnClickListener() {

125. public void onClick(View v) {

126. showItems();

127. }

128. };

129. }

130.

131. /*

132. * 重新建⽴数据表

133. */

134. private void CreateTable() {

135. //tableDatabase()语句负责得到⼀个可写的SQLite数据库,如果这个数据库还没有建⽴,

136. //那么mOpenHelper辅助类负责建⽴这个数据库。如果数据库已经建⽴,那么直接返回⼀个可写的数据库。

137. SQLiteDatabase db = tableDatabase();

138. String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE

139. + " text not null, " + BODY + " text not null " + ");";

140. Log.i("haiyang:createDB=", sql); 141.

142. try {

143. L("DROP TABLE IF EXISTS diary");

144. L(sql);

145. setTitle("数据表成功重建");

146. } catch (SQLException e) {

147. setTitle("数据表重建错误");

148. }

149. }

150.

151. /*

152. * 删除数据表

153. */

154. private void dropTable() {

155. //tableDatabase()语句负责得到⼀个可写的SQLite数据库,如果这个数据库还没有建⽴,

156. //那么mOpenHelper辅助类负责建⽴这个数据库。如果数据库已经建⽴,那么直接返回⼀个可写的数据库。

157. SQLiteDatabase db = tableDatabase();

158. String sql = "drop table " + TABLE_NAME;

159. try {

160. L(sql);

161. setTitle("数据表成功删除:" + sql);

162. } catch (SQLException e) {

163. setTitle("数据表删除错误");

164. }

165. }

166.

167. /*

168. * 插⼊两条数据

169. */

170. private void insertItem() {

171. //tableDatabase()语句负责得到⼀个可写的SQLite数据库,如果这个数据库还没有建⽴,

172. //那么mOpenHelper辅助类负责建⽴这个数据库。如果数据库已经建⽴,那么直接返回⼀个可写的数据库。

173. SQLiteDatabase db = tableDatabase();

174. String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY

175. + ") values('haiyang', 'android的发展真是迅速啊');";

176. String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY

177. + ") values('icesky', 'android的发展真是迅速啊');";

178. try {

179. // Log.i()会将参数内容打印到⽇志当中,并且打印级别是Info级别

180. // Android⽀持5种打印级别,分别是Verbose、Debug、Info、Warning、Error,当然我们在程序当中⼀般⽤到的是Info级别

181. Log.i("haiyang:sql1=", sql1);

182. Log.i("haiyang:sql2=", sql2);

183. L(sql1);

184. L(sql2);

185. setTitle("插⼊两条数据成功");

186. } catch (SQLException e) {

187. setTitle("插⼊两条数据失败");

188. }

189. }

190.

191. /*

192. * 删除其中的⼀条数据

193. */

194. private void deleteItem() {

195. try {

196. //tableDatabase()语句负责得到⼀个可写的SQLite数据库,如果这个数据库还没有建⽴,

197. //那么mOpenHelper辅助类负责建⽴这个数据库。如果数据库已经建⽴,那么直接返回⼀个可写的数据库。

198. SQLiteDatabase db = tableDatabase();

199. //第⼀个参数是数据库表名,在这⾥是TABLE_NAME,也就是diary。

200. //第⼆个参数,相当于SQL语句当中的where部分,也就是描述了删除的条件。

201. //如果在第⼆个参数当中有“?”符号,那么第三个参数中的字符串会依次替换在第⼆个参数当中出现的“?”符号。

202. (TABLE_NAME, " title = 'haiyang'", null);

203. setTitle("删除title为haiyang的⼀条记录");

204. } catch (SQLException e) {

205.

206. }

207.

208. } 209.

210. /*

211. * 在屏幕的title区域显⽰当前数据表当中的数据的条数。

212. */

213. /*

214. * Cursor cur = (TABLE_NAME, col, null, null, null, null, null)语句将查询到的数据放到⼀个Cursor 当中。

215. 这个Cursor⾥边封装了这个数据表TABLE_NAME当中的所有条列。

216. query()⽅法相当的有⽤,在这⾥我们简单地讲⼀下。

217. 第⼀个参数是数据库⾥边表的名字,⽐如在我们这个例⼦,表的名字就是TABLE_NAME,也就是"diary"。

218. 第⼆个字段是我们想要返回数据包含的列的信息。在这个例⼦当中我们想要得到的列有title、body。我们把这两个列的名字放到字符串数组⾥边来。

219. 第三个参数为selection,相当于SQL语句的where部分,如果想返回所有的数据,那么就直接置为null。

220. 第四个参数为selectionArgs。在selection部分,你有可能⽤到“?”,那么在selectionArgs定义的字符串会代替selection中的“?”。

221. 第五个参数为groupBy。定义查询出来的数据是否分组,如果为null则说明不⽤分组。

222. 第六个参数为having ,相当于SQL语句当中的having部分。

223. 第七个参数为orderBy,来描述我们期望的返回值是否需要排序,如果设置为null则说明不需要排序。

224. */

225.

226. private void showItems() {

227.

228. SQLiteDatabase db = dableDatabase();

229. String col[] = { TITLE, BODY };

230. //查询数据

231. Cursor cur = (TABLE_NAME, col, null, null, null, null, null);

232. Integer num = nt();

233. setTitle(ng(num) + " 条记录");

234. }

235. }

四.内容提供器(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并且符合⼀定条件的数据。 tProvider和ContentResolver中⽤到的Uri

在ContentProvider和ContentResolver当中⽤到了Uri的形式通常有两种,⼀种是指定全部数据,另⼀种是指定某个ID的数据。 我们看下⾯的例⼦。

content://contacts/people/ 这个Uri指定的就是全部的联系⼈数据。 content://contacts/people/1 这个Uri指定的是ID为1的联系⼈的数据。

在上边两个类中⽤到的Uri⼀般由3部分组成。 第⼀部分是:"content://" 。 第⼆部分是要获得数据的⼀个字符串⽚段。

最后就是ID(如果没有指定ID,那么表⽰返回全部)。 由于URI通常⽐较长,⽽且有时候容易出错,且难以理解。所以,在Android当中定义了⼀些辅助类,并且定义了⼀些常量来代替这些长字符串的使⽤,例如下边的代码:

T_URI (联系⼈的URI)。 1)实现的功能 在这个例⼦⾥边,⾸先在系统的联系⼈应⽤当中插⼊⼀些联系⼈信息,然后把这些联系⼈的名字和电话再显⽰出来 2)实现⽅法

1. package tProvider;

2.

3. import tivity;

4. import ;

5. import ;

6. import ;

7. import apter;

8. import CursorAdapter;

9.

10. public class ContentProviderDemo extends ListActivity {

11.

12. protected void onCreate(Bundle savedInstanceState) {

13. te(savedInstanceState);

14. //getContentResolver()⽅法得到应⽤的ContentResolver实例。

15. // query(T_URI, null, null, null, null)。它是ContentResolver⾥的⽅法,负责查询所有联系⼈,并返回⼀个Cursor。这个⽅法参数⽐较多,每个参数的具体含义如下。

16. //· 第⼀个参数为Uri,在这个例⼦⾥边这个Uri是联系⼈的Uri。

17. //· 第⼆个参数是⼀个字符串的数组,数组⾥边的每⼀个字符串都是数据表中某⼀列的名字,它指定返回数据表中那些列的值。

18. //· 第三个参数相当于SQL语句的where部分,描述哪些值是我们需要的。

19. //· 第四个参数是⼀个字符串数组,它⾥边的值依次代替在第三个参数中出现的“?”符号。

20. //· 第五个参数指定了排序的⽅式。

21. Cursor c = getContentResolver().query(T_URI, null, null, null, null);

22. startManagingCursor(c); //让系统来管理⽣成的Cursor。

23. ListAdapter adapter = new SimpleCursorAdapter(

24. this,

25. _list_item_2,

26. c,

27. new String[] { , },

28. new int[] { 1, 2 });

29. setListAdapter(adapter); //将ListView和SimpleCursorAdapter进⾏绑定。

30. }

31.

32. }

五. ⽹络存储⽅式

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689428737a246656.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信