Android SDK上手指南:应用程序数据

简介: 版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/52996965 在本系列教程当中,我们将学习如何从零开始进行Android SDK开发。
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/52996965

在本系列教程当中,我们将学习如何从零开始进行Android SDK开发。我们已经熟悉了Android应用程序的结构与基本组成元素,其中包括资源、清单与用户界面。在着手进行Android平台的功能性应用开发之后,大家肯定需要保存这样或者那样的数据信息。Android平台提供多种选项,用于打理应用程序中的数据存储任务,而这正是今天这篇文章要讨论的核心内容。

介绍

从广义上讲,Android应用中的数据存储选项共有五种主要类型:将数据保存在应用的共享偏好当中、保存在内部存储(专属于应用本身)当中、保存在外部存储(向设备公开)当中、保存在数据库当中以及保存在可通过设备互联网连接访问的Web资源当中。受篇幅所限,我们无法详细对这些选项作出论述,但会对每种方案的基础特性加以概括、从而帮助大家在需要使用持久化数据时理清存储问题的解决思路。

1. 共享偏好

第一步

共享偏好允许大家以键-值对的形式保存基本数据类型。应用程序的共享偏好文件通常被视为最简单的数据存储选项,但从本质上说它对于存储对象提出了一定程度的限制。大家可以通过它存储基本类型数字(如整数、长数以及浮点数字)、布尔值以及文本字符串。我们需要为自己保存的每个数值分配一个名称,从而在应用程序运行时据此对其进行检索。由于大家很可能在自己创建的第一款应用中就用到共享偏好,因此我们人把它作为讲解的重点、以更为详尽的方式(相较于其它选项)进行表述,从而帮助各位巩固必要知识。

大家可以在自己的主Activity类中尝试这些代码,并在稍后运行本系列教程的应用示例时对其加以测试。在理想情况下,共享偏好应该可以符合应用程序中的用户配置选项,如同选择外观设置一样。大家应该还记得,我们曾经创建过一个简单的按钮,用户点击它之后屏幕上会显示出“Ouch”文本内容。现在让我们假设自己希望用户在点击一次之后,该按钮上会持续显示“Ouch”字样,且该状态在应用程序运行过程中始终保持不变。这意味着按钮上的初始文本仅在用户首次点击操作之前存在。

让我们为应用程序添加共享偏好内容。在该类的起始位置、onCreate方法之前,我们为共享偏好选择一个名称:

 
 
  1. public static final String MY_APP_PREFS = "MyAppPrefs"; 

利用“public static”修饰符,我们可以访问处于应用内任何类中的这项变量,因此我们只需要将偏好名称字符串保存在这里即可。我们使用大写是因为该变量属于常数,“final”修饰符也是因此而存在。每一次检索或者在应用程序偏好当中设置数据条目时,大家都必须使用同样的名称。

第二步

现在我们来编写共享偏好内容。在我们的onClick方法中、按钮“Ouch”文本设置部分的下方,尝试通过名称取回这条共享偏好:

 
 
  1. SharedPreferences thePrefs = getSharedPreferences(MY_APP_PREFS, 0); 

大家需要为“android.conent.SharedPreferences”类添加一条导入。将鼠标悬停在“SharedPreferences”文本上方,并利用Eclipse提示完成导入。第一项参数是我们所定义的偏好名称,第二项则是我们作为默认选项的基本模式。

现在我们需要为共享偏好指定一套编辑器,从而实现对其中数值的设定:

 
 
  1. SharedPreferences.Editor prefsEd = thePrefs.edit(); 

现在我们可以向共享偏好当中写入值了:

prefsEd.putBoolean("btnPressed", true);

这里我们使用了布尔类型,因为当前状态只分为两种——用户已经或者尚未按下按钮。编辑器提供多种不同类型,我们可以从中选择以保存这套共享偏好,其中每种方法都拥有自己的名称与值参数。最后,我们需要提交编辑结果:

 
 
  1. prefsEd.commit(); 

第三步

现在让我们利用已经保存的值来检测用户运行应用程序后,按钮应该显示什么样的内容。在onCreate中的现有代码之后添加共享偏好:

 
 
  1. SharedPreferences thePrefs = getSharedPreferences(MY_APP_PREFS, 0); 

这一次我们不必使用编辑器,因为我们只需要获取一个值:

 
 
  1. boolean pressed = thePrefs.getBoolean("btnPressed", false); 

现在我们利用已经设置过的名称检索该值,并读取变量中的结果。如果该值尚未被设置,返回的则为第二项参数,也就是默认值——代表否定含义。现在让我们使用该值:

 
 
  1. if(pressed) theButton.setText("Ouch"); 

如果用户在应用程序运行之后按下该按钮,则按钮直接显示“Ouch”字样。在本系列的后续文章当中,大家会看到我们在应用运行中进行这一操作的情况。这个简单的例子很好地诠释了共享偏好的使用过程。大家会发现,共享偏好在帮助应用程序通过外观及使用感受迎合用户喜好方面具有重要的作用。

2. 私有内部文件

第一步

大家可以将文件保存在用户设备的内部以及外部存储当中。如果将文件保存在内部存储中,Android系统会将其视为专属于当前应用的私有数据。这类文件基本上属于应用程序的组成部分,我们无法在应用程序之外直接对其进行访问。再有,如果应用程序被移除、这些文件也会同时被清空。

大家可以利用以下输出例程在内存存储中创建一个文件:

 
 
  1. FileOutputStream fileOut = openFileOutput("my_file", Context.MODE_PRIVATE); 

大家需要为“java.io.FileOutputStream”类进行导入添加。我们提供了文件名称与模式,选择私有模式意味着该文件将只能被该应用程序所使用。如果大家现在就把这部分代码加入到Activity当中,例如onClick方法中,Eclipse将弹出错误提示。这是因为当我们进行输入/输出操作时,应用程序可能遭遇一些需要应对的错误。如果大家的输入/输出操作无法解决这类错误,Eclipse就会提示异常状况、应用程序也会中止运行。为了保证应用程序在这种情况下仍能正常运行,我们需要将自己的输入/输出代码封装在try代码块当中:

 
 
  1. try{     FileOutputStream fileOut = openFileOutput("my_file", Context.MODE_PRIVATE); 
  2. catch(IOException ioe){     
  3. Log.e("APP_TAG", "IO Exception", ioe); } 

如果输入/输出操作导致异常,那么catch块中的上述代码就会付诸执行,从而将错误信息写入到日志当中。大家今后会经常用到应用程序中的Log类(导入‘android.util.Log’),它会记录代码执行时所发生的具体情况。我们可以为字符串标签定义一个类变量,也就是上述代码中的第一条参数。这样一旦出现错误,大家就可以在Android LogCat中查看异常信息了。

第二步

现在回到try块,在创建了文件输出例程之后,大家可以尝试将以下代码写入文件:

 
 
  1. String fileContent = "my data file content"; fileOut.write(fileContent.getBytes()); 

在将所有必要内容写入数据文件之后,利用以下代码作为结尾:

 
 
  1. fileOut.close(); 

第三步

当大家需要检索内部文件中的内容时,可以通过以下流程实现:

 
 
  1. try{    
  2.  FileInputStream fileIn = openFileInput("my_file");     
  3. //read the file } catch(IOException ioe){     
  4. Log.e("APP_TAG", "IO Exception", ioe); } 

在try块当中,利用利用缓冲读取器读取文件内容:

 
 
  1. InputStreamReader streamIn = new InputStreamReader(fileIn); 
  2. BufferedReader fileRead = new BufferedReader(streamIn); 
  3. StringBuilder fileBuild = new StringBuilder(""); 
  4. String fileLine=fileRead.readLine(); while(fileLine!=null){    
  5.  fileBuild.append(fileLine+"\n");     
  6. fileLine=fileRead.readLine(); } 
  7. String fileText = fileBuild.toString(); streamIn.close(); 

大家不要被其中所涉及的大量不同对象所吓倒,这其实属于标准的Java输入/输出操作。其中的while循环会在文件中的每一行执行一次。在执行完成后,“fileText”变量将把文件内容保存为字符串、以备我们直接使用。

3. 公共外部文件

第一步

只要用户设备支持,我们的应用程序也可以将文件保存在外部存储当中。外部存储种类繁多,包括SD卡、其它便携式介质或者用户无法移除但被系统认定为外部类型的内存存储机制。当我们将文件保存在外部存储中时,其内容将完全公开、大家也无法以任何方式阻止用户或者其它应用对其进行访问。

在我们尝试将数据保存在外部存储中之前,必须首先检查对应存储机制是否可用——尽量避免意外状况绝对是种好习惯:

 
 
  1. String extStorageState = Environment.getExternalStorageState(); 

系统会将信息以字符串的形式返回,大家可以对其进行分析、并与Environment类中的外部存储状态字段加以比对:

 
 
  1. if(Environment.MEDIA_MOUNTED.equals(extStorageState)){     
  2. //ok to go ahead and read/ write to external storage } 
  3. else if(Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)){    
  4.  //can only read } else{     //cannot read or write } 

即使设备上确实存在外部存储,我们也不能先入为主地假定应用可以向其写入数据。

第二步

在证实了我们确实能够向外部存储写入数据之后,大家接下来需要检索目录以指定文件保存的位置。以下应用程序设置内容指向八级及更高API:

 
 
  1. File myFile = new File(getExternalFilesDir(null), "MyFile.txt"); 

这样大家就可以对该文件进行写入与读取了。不过也别忘了在项目的清单文件中添加以下仅限:

 
 
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

随着我们开发的应用程序变得愈发复杂,大家可能希望将自己保存得到的文件与其它应用共享。在这种情况下,大家可以使用公共目录下的各类通用条目,例如图片以及音乐文件。

4. 数据库

随着我们的应用程序所涉及的复杂结构数据越来越多,共享偏好或者内部/外部文件可能已经无法满足实际需求,这时候大家就应该考虑使用数据库方案了。Android支持开发人员在应用程序内部创建并访问SQLite数据库。在我们创建一套数据库时,其将作为私有组件服务单纯服务于相关应用程序。

在Android应用中利用SQLite数据库的方法多种多样,推荐大家使用扩展SQLiteOpenHelper的类来实现这方面需求。在该类当中,我们需要定义数据库属性、创建各种类变量(包括我们所定义的数据库列表名称及其SQL创建字符串),具体代码如下所示:

 
 
  1. private static final String NOTE_TABLE_CREATE =     "CREATE TABLE Note (noteID INTEGER PRIMARY KEY AUTOINCREMENT, " +     "noteTxt TEXT);"; 

这里所举的例子只涉及一套非常简单的表格,其中包含两列,一列内容为ID、另一列内容为文本;两列都用于记录用户注释信息。在SQLiteOpenHelper类当中,大家可以重写onCreate方法来创建自己的数据库。在应用程序的其它部分当中,例如Activity类中,大家可以通过SQLiteOpenHelper实现对数据库的访问,并利用WritableDatabase方法插入新记录、利用getReadableDatabase方法来查询现有记录,而后将结果显示在应用程序UI当中。

在对查询结果进行迭代时,我们的应用程序将使用Cursor类——该类会依次引用结果集中的每一行内容。

5. 互联网数据

很多应用都会使用互联网数据资源,而且某些应用甚至基本是由一套界面与大量Web数据源所构成。大家可以利用用户设备上的互联网连接来存储并检索来自Web的数据,只要网络连接有效、这一机制就能正常运作。为了实现这一目标,我们需要在自己的清单文件中添加“android.permission.INTERNET”权限。

如果我们希望自己的应用能够从互联网中获取数据,则必须保证这一流程脱离应用主UI线程。利用AsyncTask,大家可以通过后台进程的方式从Web源获取数据、在数据下载完成后将结果写入UI、最后让UI正常执行自身功能。

大家还可以将一个内部AsyncTask类添加到Activity类当中,并在需要获取数据的时候在该Activity中创建一个AsyncTask实例。通过在AsyncTask中引入doInBackground与onPostExecute两种方法,大家可以检索Activity中所获取到的数据并将其写入用户界面。

获取Web数据在应用开发工作当中属于中等难度的任务,大家最好在熟练掌握了Android开发知识之后再进行尝试。不过大家可能很快就会发现,这样的数据获取机制对不少应用都非常适合,因为这能有效利用用户设备的连接资源。Java与Android都提供相关工具,用于处理返回的结构化数据——例如JSON feed。

结论

在今天的文章中,我们基本了解了开发Android应用程序时需要接触到的数据存储方案。无论大家最终选择哪种方案,都应该以实际需求作为参考标准,因为不同的方案只适合特定需求。在本系列教程的下一篇当中,我们将共同探讨如何将物理设备与已安装的Eclipse相连、同时学习如何创建虚拟设备。在此之后,我们还将探索如何让应用程序运行在这两种类型的设备之上。顺便向大家报告,再有两篇文章本系列教程就将彻底结束;在最后一篇文章中,我们将研究通用类以及Android Activity生命周期,从而帮助大家做好开发应用程序的一切准备。

目录
相关文章
|
16天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
1天前
|
缓存 移动开发 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【4月更文挑战第18天】 在移动开发的世界中,打造一个既快速又流畅的Android应用并非易事。本文深入探讨了如何通过一系列创新的技术策略来提升应用性能和用户体验。我们将从用户界面(UI)设计的简约性原则出发,探索响应式布局和Material Design的实践,再深入剖析后台任务处理、内存管理和电池寿命优化的技巧。此外,文中还将讨论最新的Android Jetpack组件如何帮助开发者更高效地构建高质量的应用。此内容不仅适合经验丰富的开发者深化理解,也适合初学者构建起对Android高效开发的基础认识。
2 0
|
1天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
5 0
|
3天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。
|
3天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android's AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
5 0
|
3天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
5 0
|
5天前
|
搜索推荐 开发工具 Android开发
安卓即时应用(Instant Apps)开发指南
【4月更文挑战第14天】Android Instant Apps让用户体验部分应用功能而无需完整下载。开发者需将应用拆分成模块,基于已上线的基础应用构建。使用Android Studio的Instant Apps Feature Library定义模块特性,优化代码与资源以减小模块大小,同步管理即时应用和基础应用的版本。经过测试,可发布至Google Play Console,提升用户便利性,创造新获客机会。
|
6天前
|
Java API 调度
安卓多线程和并发处理:提高应用效率
【4月更文挑战第13天】本文探讨了安卓应用中多线程和并发处理的优化方法,包括使用Thread、AsyncTask、Loader、IntentService、JobScheduler、WorkManager以及线程池。此外,还介绍了RxJava和Kotlin协程作为异步编程工具。理解并恰当运用这些技术能提升应用效率,避免UI卡顿,确保良好用户体验。随着安卓技术发展,更高级的异步处理工具将助力开发者构建高性能应用。
|
6天前
|
编解码 人工智能 测试技术
安卓适配性策略:确保应用在不同设备上的兼容性
【4月更文挑战第13天】本文探讨了提升安卓应用兼容性的策略,包括理解平台碎片化、设计响应式UI(使用dp单位,考虑横竖屏)、利用Android SDK的兼容工具(支持库、资源限定符)、编写兼容性代码(运行时权限、设备特性检查)以及优化性能以适应低端设备。适配性是安卓开发的关键,通过这些方法可确保应用在多样化设备上提供一致体验。未来,自动化测试和AI将助力应对设备碎片化挑战。
|
12天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。