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)
    {

    }
    
    原文作者:nancymi
    原文地址: https://www.jianshu.com/p/f64a1c449c16
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞