20189200余超 2018-2019-2 移动平台应用开发实践第十周作业

偏好

在Android应用中,我们常需要记录用户设置的一些偏好参数,,此时我们就需要用SharedPreferences和Editor将这些信息保存下来,在下次登录时读取。

SharedPreferences保存的数据主要类似于配置信息格式的数据,因此它保存数据的形式为key-value对,下面我们来看下实例代码。

首先是界面布局,比较简单,就是一个普通的登陆界面.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity" >
<EditText android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/account"/>
<EditText android:layout_width="fill_parent"android:layout_height="wrap_content"android:id="@+id/password"android:layout_below="@id/account"/>
<Button android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@id/password"android:text="保存参数"android:id="@+id/save"android:onClick="save"/>
</RelativeLayout>

这是自定义的Preferences 类,用来实现数据的保存 ,可在Android的内置存储空间产生一文件。

import android.R.integer;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.widget.EditText;public class Preferences {private Context context;public Preferences(Context context){this.context=context;}public void save(String name, Integer valueOf) {//保存文件名字为"shared",保存形式为Context.MODE_PRIVATE即该数据只能被本应用读取SharedPreferences preferences=context.getSharedPreferences("shared",Context.MODE_PRIVATE);Editor editor=preferences.edit();editor.putString("name", name);editor.putInt("age", valueOf);editor.commit();//提交数据}
}

下面是Mainactivity的代码。在activity的oncreate阶段我们加载本地的数据。

import java.util.HashMap;
import java.util.Map;import android.R.integer;
import android.os.Bundle;
import android.app.Activity;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;public class MainActivity extends Activity {private EditText account,passworad;Preferences prefer;//自定义的类SharedPreferences preference; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);account=(EditText)findViewById(R.id.account);passworad=(EditText)findViewById(R.id.password);//获取本地的数据preference=getSharedPreferences("shared", MODE_PRIVATE);Map<String, String> map=new HashMap<String, String>();map.put("name",preference.getString("name",""));map.put("age", String.valueOf(preference.getInt("age", 0)));        account.setText(map.get("name"));passworad.setText(map.get("age"));}//保存文件的方法public void save(View v) {String name=account.getText().toString();String age=passworad.getText().toString();prefer=new Preferences(this);prefer.save(name,Integer.valueOf(age));Toast.makeText(getApplicationContext(), "保存完成", Toast.LENGTH_SHORT).show();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}

我们看一下效果.

点击保存参数,出现保存完成则说明我们已经保存成功了,在下次登录的时候可以看到这些参数还在。因为记录文件是在内置空间中的,所以我们在SD卡中找不到该文件,

如果有root权限的手机可以下载个RE文件管理,我们可以再/data/data/的路径找到很多应用程序的内置文件夹,我们可以在这些文件夹中看到一个shared_prefs文件夹,

里面就有我们刚刚设置而产生的xml文件。

操作空间

我们先来考虑这样一个问题:

打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的时候又是清除的哪里的数据?读完本文相信你会有答案。

在android开发中我们常常听到这样几个概念,内存,内部存储,外部存储,很多人常常将这三个东西搞混,那么我们今天就先来详细说说这三个东西是怎么回事?

内存,我们在英文中称作memory,内部存储,我们称为InternalStorage,外部存储我们称为ExternalStorage,这在英文中本不会产生歧义,但是当我们翻译为中文之后,前两个都简称为内存,于是,混了。

那么究竟什么是内部存储什么是外部存储呢?

首先我们打开DDMS,有一个File Explorer,如下:

彻底理解android中的内部存储与外部存储0

这里有三个文件夹需要我们重视,一个是data,一个是mnt,一个是storage,我们下面就详细说说这三个文件夹。

1.内部存储

data文件夹就是我们常说的内部存储,当我们打开data文件夹之后(没有root的手机不能打开该文件夹),里边有两个文件夹值得我们关注,如下:

一个文件夹是app文件夹,还有一个文件夹就是data文件夹,app文件夹里存放着我们所有安装的app的apk文件,其实,当我们调试一个app的时候,可以看到控制台输出的内容,有一项是uploading .....就是上传我们的apk到这个文件夹,上传成功之后才开始安装。另一个重要的文件夹就是data文件夹了,这个文件夹里边都是一些包名,打开这些包名之后我们会看到这样的一些文件:

1.data/data/包名/shared_prefs
2.data/data/包名/databases
3.data/data/包名/files

4.data/data/包名/cache

如果打开过data文件,应该都知道这些文件夹是干什么用的,我们在使用sharedPreferenced的时候,将数据持久化存储于本地,其实就是存在这个文件中的xml文件里,我们App里边的数据库文件就存储于databases文件夹中,还有我们的普通数据存储在files中,缓存文件存储在cache文件夹中,存储在这里的文件我们都称之为内部存储。

2.外部存储

外部存储才是我们平时操作最多的,外部存储一般就是我们上面看到的storage文件夹,当然也有可能是mnt文件夹,这个不同厂家有可能不一样。

一般来说,在storage文件夹中有一个sdcard文件夹,这个文件夹中的文件又分为两类,一类是公有目录,还有一类是私有目录,其中的公有目录有九大类,比如DCIM、DOWNLOAD等这种系统为我们创建的文件夹,私有目录就是Android这个文件夹,这个文件夹打开之后里边有一个data文件夹,打开这个data文件夹,里边有许多包名组成的文件夹。

说到这里,我想大家应该已经可以分清楚什么是内部存储什么是外部存储了吧?好,分清楚之后我们就要看看怎么来操作内部存储和外部存储了。

3.操作存储空间

首先,经过上面的分析,大家已经明白了,什么是内部存储,什么是外部存储,以及这两种存储方式分别存储在什么位置,一般来说,我们不会自己去操作内部存储空间,没有root权限的话,我们也没法操作内部存储空间,事实上内部存储主要是由系统来维护的。不过在代码中我们是可以访问到这个文件夹的。由于内部存储空间有限,在开发中我们一般都是操作外部存储空间,Google官方建议我们App的数据应该存储在外部存储的私有目录中该App的包名下,这样当用户卸载掉App之后,相关的数据会一并删除,如果你直接在/storage/sdcard目录下创建了一个应用的文件夹,那么当你删除应用的时候,这个文件夹就不会被删除。

经过以上的介绍,我们可以总结出下面一个表格:

一目了然,什么是内部存储,什么是外部存储。

如果按照路径的特征,我们又可以将文件存储的路径分为两大类,一类是路径中含有包名的,一类是路径中不含有包名的,含有包名的路径,因为和某个App有关,所以对这些文件夹的访问都是调用Context里边的方法,而不含有包名的路径,和某一个App无关,我们可以通过Environment中的方法来访问。如下图:

操作数据库

public class MainActivity extends AppCompatActivity {private MyDatabaseHelper dbHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 3); // 执行这句并不会创建数据库文件Button btnCreateDatabase = (Button) findViewById(R.id.button);btnCreateDatabase.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {dbHelper.getWritableDatabase(); // 执行这句才会创建数据库文件}});}
}
public class MyDatabaseHelper extends SQLiteOpenHelper {public static final String CREATE_BOOK = "create table book (" +"id integer primary key autoincrement, " +"author text, " +"price real," +"pages integer, " +"name text)";private Context mContext;public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);mContext = context;}/*** 数据库已经创建过了, 则不会执行到,如果不存在数据库则会执行* @param db*/@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_BOOK); // 执行这句才会创建表Toast.makeText(mContext, "create succeeded", Toast.LENGTH_SHORT).show();}/*** 创建数据库时不会执行,增大版本号升级时才会执行到* @param db* @param oldVersion* @param newVersion*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 在这里面可以把旧的表 drop掉 从新创建新表,// 但如果数据比较重要更好的做法还是把旧表的数据迁移到新表上,比如升级qq聊天记录被删掉肯定招骂Toast.makeText(mContext, "onUpgrade oldVersion:" + oldVersion + " newVersion:" + newVersion, Toast.LENGTH_SHORT).show();}
}

验证数据库文件是否存在的方法看最后部分

剩下的工作就是对数据库表的增删改查了

首先通过下面的代码获得一个引用以便操作数据库

1 SQLiteDatabase db = dbHelper.getWritableDatabase();

对于增删改都可以用 db.execSQL(String sql); 来执行sql语句。 例如增加一条记录

1 db.execSQL("insert into book(name , author, pages, price) values("Android数据库操作指南", "panda fang", 200, 35.5)");

遇到字符串要转义 有没有觉得很蛋疼, 用下面的方法就好多了

1 db.execSQL("insert into book(name , author, pages, price) values(?, ? ,? ,? )", new String[]{"Android数据库操作指南", "panda fang", "200", "35.5"});

sql 中用 ? 占位 后面传入真正的参数, 由于在创建表的时候已经约定pages 和 price字段的数据类型为integer和real, 虽然代码中写的是字符串并不影响,存入数据库会自动处理的。数组嘛,必须与其他的元素类型一致。 这第二个方式是 execSQL(String sql)的重载方法 api是 public void execSQL(String sql, Object[] bindArgs) throws SQLException

对于查询则要使用 rawQuery(String sql, String[] selectionArgs) , 因为 execSQL返回void ,而查询需要访问查询结果。方法如下:

Cursor cursor =  db.rawQuery("select * from book", null);
while (cursor.moveToNext())
{String name = cursor.getString(cursor.getColumnIndex("name"));String author =  cursor.getString(cursor.getColumnIndex("author"));Log.i(TAG, "name:" + name + " author:" + author);
}
cursor.close();

如何检查数据库文件是否存在,以及检查表中的数据呢。

前提是使用模拟器或者root过的真机。从 android studio 菜单中 Tools -> Android -> Android Device Monitor -> File Explorer 找到 data/data/程序包名/databases 目录

查看是否存在数据库文件。如果存在可以导出到电脑上, 用 以下工具查看数据库中的表

获取图片

import java.io.FileNotFoundException;import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;import com.maikefengchao.daixu.R;public class WriteArticle_CompeterelayActivity extends BaseActivity {private ImageView im_upload_img;@Overridepublic void initView(Bundle savedInstanceState){setContentView(R.layout.view_write_competerelay);im_upload_img = (ImageView)findViewById(R.id.write_competerelay_cover_iv);}@Overrideprotected void setListener() {im_upload_img.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();/* 开启Pictures画面Type设定为image */intent.setType("image/*");/* 使用Intent.ACTION_GET_CONTENT这个Action */intent.setAction(Intent.ACTION_GET_CONTENT);/* 取得相片后返回本画面 */startActivityForResult(intent, 1);}});}@Overrideprotected void processLogic(Bundle saveInstanceState) {}//获取本地图片@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {Uri uri = data.getData();String img_url = uri.getPath();//这是本机的图片路径ContentResolver cr = this.getContentResolver();try {Bitmap bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri));ImageView imageView = (ImageView) findViewById(R.id.write_competerelay_cover_iv);/* 将Bitmap设定到ImageView */imageView.setImageBitmap(bitmap);} catch (FileNotFoundException e) {Log.e("Exception", e.getMessage(),e);}}super.onActivityResult(requestCode, resultCode, data);}
}

statistics.sh

转载于:https://www.cnblogs.com/yuchao123/p/10808757.html

20189200余超 2018-2019-2 移动平台应用开发实践第十周作业相关推荐

  1. 20189200余超 2018-2019-2 移动平台应用开发实践第七周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第七周作业 布局 在这一节中首先学习了java的页面布局,在此基础之上来进行了编程. 图片如下: 代码如下: *** 使用代码进行登录 ...

  2. 20189200余超 2018-2019-2 移动平台应用开发实践第六周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第六周作业 Android简介.活动.UI组件 1.Android系统架构 这是Android系统架构图,够一目了然了吧,Androi ...

  3. 20189200余超 2018-2019-2 移动平台应用开发实践第八周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第八周作业 ListView 1.自定义BaseAdapter,然后绑定ListView的最简单例子 先看看我们要实现的效果图: 一个 ...

  4. 20189200余超 2018-2019-2 移动平台应用开发实践第十一周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第十一周作业 制作视频 本节是Android多媒体基本API调用的一节,带来的是MediaRecord的简单使用, 用法非常简单,我们 ...

  5. 20189200余超 2018-2019-2 移动平台应用开发实践第三周作业

    2018-2019-2 移动平台应用开发实践第三周作业 核心类 基本类型的封装类 封装类: java语言认为一切皆对象.8个基本数据类型野应该具备对应的对象.通过封装类可以把8个基本类型的值封装对象进 ...

  6. 20189200余超 2018-2019-2 移动平台应用开发实践第十二周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第十二周作业 服务 Service的声明 Service是Android中的四大组件,使用它一定要在AndroidManifest.x ...

  7. 20189200余超 2018-2019-2 移动平台应用开发实践第五作业

    20189200余超 2018-2019-2 移动平台应用开发实践第五作业 输入/输出 输入输出可以说是计算机的基本功能.作为一种语言体系,java中主要按照流(stream)的模式来实现.其中数据的 ...

  8. 20189200余超 2018-2019-2 移动平台应用开发实践第九周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第九周作业 图形和制定视图 Android视图系统.层次关系 Android应用设计和Web应用设计类似,也分前端和后端设计.Andr ...

  9. 20189200余超 2018-2019-2 移动平台应用开发实践作项目代码分析

    20189200余超 2018-2019-2 移动平台应用开发实践作项目代码分析 项目名称 小说阅读器 项目功能 注册登录 用户信息.用户密码.用户图像修改 书籍分类 书架 书籍搜索(作者名或书籍名) ...

最新文章

  1. 【数据分析】百度内部报告解析00后移动互联网行为
  2. Time to First Byte(TTFB)与Web性能优化
  3. git分支操作、分支合并冲突解决
  4. 八、朴素贝叶斯中文分类实战
  5. android 代码 shape,Android Shape控件美化实现代码
  6. 国外著名java技术资料网站
  7. 写在弥勒宝贝两周年之际
  8. ioc控制反转_深入理解依赖注入(DI)和控制反转(IOC)
  9. maven+springmvc出现:java.sql.SQLException: Unknown system variable 'query_cache_size'
  10. 光伏发电系统最大功率点跟踪MPPT matlab/simulink仿真 扰动观察法
  11. Python2.7打包的exe文件反编译成py文件
  12. MATLAB含有绝对值的线性规划,Lingo求解带绝对值的线性规划模型
  13. 把计算机怎么连接手机的网络助手在哪里,怎么将手机网络通过USB共享给电脑
  14. 经纬度差和米单位的换算
  15. Kalman详尽原理介绍合集
  16. 获取DOM元素后,对NodeList的遍历的几种方法
  17. 刷题日记 acwing 2058笨拙的手指 位运算的运用,迭代器的使用,秦九稍(别的进制转化为10进制)
  18. Decoding tumour phenotype by noninvasive imaging using a quantitative radiomics approach
  19. 你好,C++(40)7.1 一切指针都是纸老虎:彻底理解指针
  20. 常用交换机的配置命令

热门文章

  1. AIT Worldwide Logistics与卡利塔航空建立民航预备队合作伙伴关系
  2. vad算法 c语言,腾讯视频cKey算法
  3. ps cs6选择并遮住在哪设置
  4. 前端下载 “不支持打开该类型文件或文件已损坏“问题
  5. Centos7安装cuda10.1
  6. msysgit在Windows上的安装,
  7. 大学生“挑战杯”创业计划大赛财务分析估算方法与技巧【转】
  8. pom 文件的project标签报错Failed to read artifact descriptor for xxx:jar
  9. 图像处理:U-Net中的重叠-切片(Overlap-tile)
  10. 匿名内部类的定义格式