Android面试简录——文件存储


* SharedPreferences

  • 请描述Android SDK支持哪些文件存储技术?
    1.SharedPreferences保存key-value类型的数据
    2.流文件存储(openFileOutput/openFileInput或FileInputStream/FileOutputStream)
    3.XML半结构化存储
    4.用JSON保存数组和对象
    5.用数据库保存结构化数据
    6.用第三方的面向对象数据库直接保存Java对象

  • 如何使用SharedPreferences存取key-value类型的数据?
    1.Context.getSharedPreferences(参数1:存储key-value的文件名称,...) -> SharedPreferences对象
    2.SharedPreferences.edit -> SharedPreferences.Editor对象
    3.SharedPreferences.Editor.putXxx() -> 保存key-value对
    4.SharedPreferences.Editor.commit -> 提交key-value对
    从survey.xml文件中读取key-value对:
    String PREFERENCE_NAME = "survey";
    SharedPreferences sharedPreferences = getSharedPreferences(
    PREFERENCE_NAME, Activity.MODE_PRIVATE);
    etName.setText(sharedPreferences.getString("name", ""));
    etHabit.setText(sharedPreferences.getString("habit", ""));
    cbEompanyType.check(sharedPreferences.getInt("companyTypeId", ""));
    cbEmployee.setChecked(sharedPreferences.getBoolean("employee", false));
    rgCompanyType.check(sharedPreferences.getInt("companyTypeId", -1));
    向survey.xml文件中写入key-value对:
    SharedPreferences mySharedPreferences = getSharedPreferences(
    PREFERENCE_NAME, Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = mySharedPreferences.edit();
    editor.putString("name", "bill");
    editor.putString("habit", "swimming");
    editor.putBoolean("employee", true);
    editor.putInt("companyTypeId", 1);
    editor.edit();

  • 用SharedPreferences保存的数据文件放在哪个目录中?怎样不使用SharePreferences访问这些文件?
    存储路径:/data/data/packagename/shared_prefs.
    只能使用文件流读写SharedPreferences数据文件。
    String path = android.os.Environment.getDataDirectory().getAboslutePath()
    + "/data/" + getPackageName() + "/shared_prefs/abc.xml";
    try {
    BufferedReader br = new BufferedReader(
    new InputStreamReader(
    new FileInputStream(path)));
    Toast.makeText(this, br.readLine(), Toast.LENGTH_LONG);
    fis.close();
    } catch (Exception e) {

    }
    
  • SharedPreferences怎样把数据文件存储到sd卡上?
    SharedPreference原则上只能保存在当前应用程序私有的shared_prefs目录中,不过可以利用反射技术改变系统内定的文件保存路径。
    try {
    Field field = ContextWrapper.class.getDeclaredField("mBase");
    field.setAccessible(true);
    Object obj = field.get(this);
    field = obj.getClass().getDeclaredField("mPreferencesDir");
    field.setAccessible(true);
    File file = new File("/sdcard/");
    field.set(obj, file);
    SharedPreferences mySharedPreferences = getSharedPreferences("config", Activity.MODE_PRIVATE);
    SharedPreferences.Editor editor = mySharedPreferences.edit();
    editor.putString("name", "nancy");
    editor.commit();
    } catch (Exception e) { }

  • SharedPreferences文件可以保存图像数据吗?
    将图像转换成字符串再保存。采用Base64将二进制数据转换成字符串的编码。
    SharedPreferences sharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ((BitmapDrawable) imageView.getDrawable()).getBitmap().compress(CompressFormat.JPEG, 50, baos);
    String imageBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
    SharedPreferences.Editor editor = SharedPreferences.edit();
    editor.putString("productImage", imageBase64);
    editor.commit();
    读取:
    String imageBase64 = sharedPreferences.getString("productImage", "");
    base64Bytes = Base64.decodeBase64(imageBase64.getBytes());
    bais = new ByteArrayInputStream(base64Bytes);
    imageView.setImageDrawable(Drawable.createFromStream(bais, "product_image"));

【拓展】在SharedPreferences中存取可序列化对象。
序列化对象类:
public class Product implements Serializable {
private String name;
private String id;
private String price;
//...
}
保存:
Product product = new Product();
product.setId(1234);
product.setName("nancy");
product.setPrice("9999");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.setObject(product);
SharedPreferences sharedPreferences = getSharedPreferences("Product", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
String productBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
editor.putString("product", productBase64);
editor.commit();
读取:
String productBase64 = sharedPreferences.getString("product", "");
byte[] base64Bytes = Base64.decodeBase64(productBase64.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Product product = (Product) ois.readObject();

  • 如何通过PreferenceActivity类实现一个设置页面?
    通过xml配置文件来描述设置界面的设置项,系统会自动保存当前设置项的最后状态。
    常用设置项:
    1.CheckBoxPreference:创建CheckBox标签
    2.EditTextPreference:弹出带EditText的对话框
    3.ListPreference:弹出带ListView的对话框
    res/xml目录下的preference_setting文件:
    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="我的位置源">
    <CheckBoxPreference android:key="wireless_network"
    android:title="使用无线网络"
    android:summary="使用无线网络查看应用程序的位置" />
    <CheckBoxPreference android:key="gps_satellite_setting"
    android:title="启用卫星定位"
    android:summary="定位时,精确到街道级别" />
    </PreferenceCategory>
    <PreferenceCategory android:title="个人信息设置">
    <CheckBoxPreference android:key="yesno_save_individual_info"
    android:title="是否保存个人信息" />
    <EditTextPreference android:key="individual_name"
    android:title="姓名"
    android:summary="请输入真实姓名" />
    <PreferenceScreen android:key="other_individual_msg"
    android:title="其他信息"
    android:summary="是否工作、手机" >
    <CheckBoxPreference android:key="mobile"
    android:title="手机"
    android:summary="请输入真实的手机号" />
    <CheckBoxPreference android:key="is_an_employee"
    android:title="是否工作" />
    </PreferenceScreen>
    </PreferenceCategory>
    </PreferenceScreen>
    配置:
    addPreferencesFromResource(R.xml.preference_setting);

【拓展】使用PreferenceActivity预定义组件布局界面应注意什么?
1.一个设置界面对应一个<PreferenceScreen>标签
2.<PreferenceCategory>表示一个设置分类,title属性表示分类名称
3.设置项标签可以不属于任何设置分类
4.嵌套<PreferenceScreen>,说明该设置页有一个子设置页
5.android:key属性的值是保存在XML文件中的key-value的key
6.android:title,android:summary表示设置项的标题和摘要

  • 请说出PreferenceActivity保存数据文件的路径,文件的命名规则,默认的文件名是否可以更改。
    默认保存路径:shared_prefs目录
    默认文件名:packagename_preferences.xml
    如果当前窗口属于net.blogjava.mobile包,则默认文件名为net.blogjava.mobile_packagename_preferences.xml
    修改默认的文件名:PreferenceManager.setSharedPreferencesName:
    getPreferenceManager().setSharedPreferencesName("setting");
  • 用PreferenceActivity实现一个设置界面,如果某一个设置项的复选框变化后要求设置另一个列表项的状态,应该如何做呢?
    覆盖PreferenceActivity.onPreferenceTreeClick方法:
    public boolean onPreferenceTreeOnClick(PreferenceScreen preferenceScreen, Preference preference) {
    if ("yesno_save_individual_info".equals(preference.getKey())) {
    findPreference("individual_name").setEnabled(
    !findPreference("individual_name").isEnabled());
    }
    return super.onPreferenceTreeOnClick(preferenceScreen, Preference);
    }

* 流文件

  • Android SDK支持哪些获取文件输入输出流的方式?
    1.直接创建FileInputStream和FileOutputStream对象
    try {
    FileOutputStream fos = new FileOutputStream("/sdcard/record.txt");
    //写入内容
    fos.close();
    FileInputStream fis = new FileInputStream("/sdcard/record.txt");
    //读取内容
    fis.close();
    } catch (Exception e) { }
    2.使用Context.openFileOutput/Context.openFileInput方法
    try {
    OutputStream os = openFileOutput("file.txt", Activity.MODE_PRIVATE);
    //写入内容
    os.close();
    InputStream is = openFileInput("file.txt");
    is.close();
    } catch(Exception e) { }
  • 请说出Context.openFileOutput方法存储数据文件的路径
    /data/data/<package name>/files
  • 如何使用ImageView组件装载SD卡上的图像文件?
    ImageView imageView = (ImageView) findViewById(R.id.imageView);
    imageView.setImageDrawable(Drawable.createFromPath("/sdcard/face.png"));

XML存储

  • Android SDK支持读取XML吗?
    只支持采用SAX技术读取XML。

  • 请描述SAX分析XML文档的过程
    SAX引擎需要处理5个分析点(分析事件):
    1.开始分析XML文件。DefaultHandler.startDocument,初始化工作。
    2.开始处理每一个XML元素。startElement,获得当前元素的名称、元素属性的相关信息。
    3.处理完一个XML元素。endElement,获得当前处理完的元素的全部信息。
    4.处理完XML文件。endDocument,非必需方法,收尾工作(释放资源等)。
    *6.读取字符分析点。最重要。保存SAX引擎读取的XML文件内容,就是保存XML元素的文本。

  • 将XML文件转换成对象。
    xml文件示例:
    <?xml version="1.0" encoding="utf-8"?>
    <products>
    <product>
    <id>10</id>
    <name>电脑</name>
    <price>2067.25</price>
    </product>
    <product>
    <id>20</id>
    <name>微波炉</name>
    <price>520</price>
    </product>
    </products>
    List<Product>对象
    package net.blogjava.mobile;

    public class Product
    {
        private int id;
        private String name;
        private float price;
        //...getter and setter
    }
    XML2Product类负责具体的转换工作:
    package net.blogjava.mobile;
    
    import java.util.ArrayList;
    import java.util.net;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    public class XML2Product extenda DefaultHandler
    {
        private List<Product> products;
        private Product product;
        private StringBuffer buffer = new StringBuffer();
        public List<Product> getProducts()
        {
                return products;
        }
    }
    
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException
    {
            //将SAX引擎扫描到的内容保存在buffer变量中,并为endElement提供参数
        buffer.append(ch, start, length);
        super.characters(ch, start, length);
    }
    
    @Override
    public void endElement(String uri, String localName, String gName) throws SAXException
    {
        //SAX每分析完一个XML元素,将该元素的文本保存在Product对象的相应属性中
        super.endElement(uri, localName, gName);
    }
    
    @Override
    public void sartDocument() throws SAXException
    {
            //创建用于保存转换结果的List<Product>对象
        products = new ArrayList<Product>();
    }
    
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) thows SAXException
    {
        //SAX引擎分析到每一个<product>结点时,创建一个Product对象
        super.startElement(uri, localName, qName, attributes);
    }
    
  • 补充endElement和startElement中的代码。
    @Override
    public void endElement(String uri, String localName, String gName) throws SAXException
    {
    if (localName.equals("product"))
    {
    products.add(product);
    }
    else if (localName.equals("id"))
    {
    product.setId(Integer.parseInt(buffer.toString().trim()));
    buffer.setLength(0);
    }
    else if (localName.equals("name"))
    {
    product.setName(buffer.toString().trim());
    buffer.setLength(0);
    }
    else if (localName.equals("price"))
    {
    product.setPrice(Float.parseFloat(buffer.toString().trim()));
    buffer.setLength(0);
    }
    super.endElement(uri, localName, gName);
    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) thows SAXException
    {
    if (localName.equals("product"))
    {
    product = new Product();
    }
    super.startElement(uri, localName, qName, attributes);
    }

  • 写出利用XML2Product类将products.xml文件的内容转换成List<Product>对象的Java代码。
    FileInputStream fis = new FileInputStream("/sdcard/products.xml");
    XML2Product xml2Product = new XML2Product();
    android.util.Xml.parse(fis, Xml.Encoding.UTF_8, xml2Product);
    List<Product> products = xml2Product.getProducts();


JSON存储

  • 请描述JSON文档的格式
    使用字符串形式保存数组和对象属性值。
    数组使用'[]',对象使用'{}'。

  • 请解析JSON格式文档的Java代码,并输出到LogCat视图中。
    [{'name':'地球', 'satellite_count':'1', 'satellite_names':'moon'},{'name':'火星', 'satellite_count':'2', 'satellite_names':'Phobos, Deimos'}]
    try
    {
    String json = "[{'name':'地球', 'satellite_count':'1', 'satellite_names':'moon'},{'name':'火星', 'satellite_count':'2', 'satellite_names':'Phobos, Deimos'}]";
    JSONArray jsonArray = new JSONArray(json);
    for (int i = 0; i < jsonArray.length(); i ++)
    {
    String s = String.valueOf(jsonArray.get(i));
    JSONObject jsonObject = new JSONObject(s);
    Log.d("name", String.valueOf(jsonObject.get("name")));
    Log.d("satellite_count", String.valueOf(jsonObject.get("satellite_count")));
    if (jsonObject.has("satellite_names"))
    {
    Log.d("satellite_names", String.valueOf(jsonObject.get("satellite_names")));
    }
    }
    }
    catch (Exception e)
    {

    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容