<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據

    本文為《Android/OPhone開發完全講義》一書的內容連載。轉載請注明出處

        我們知道SharedPreferences只能保存簡單類型的數據,例如,String、int等。如果想用SharedPreferences存取更 復雜的數據類型(類、圖像等),就需要對這些數據進行編碼。我們通常會將復雜類型的數據轉換成Base64編碼,然后將轉換后的數據以字符串的形式保存在 XML文件中。

    Android SDK中并未提供Base64編碼和解碼庫。因此,需要使用第三方的jar包。在本例中使用了Apache Commons組件集中的Codec組件進行Base64編碼和解碼。讀者可以從如下的地址下載Codec組件的安裝包。

    http://commons.apache.org/codec/download_codec.cgi

        在Android工程目錄的lib子目錄中已經包含了Codec組件的jar包(commons-codec-1.4.jar),因此,讀者可以在該工程中直接使用Codec組件。

        在本例中將一個Product類的對象實例和一個圖像保存在XML文件中,并在程序重新運行后從XML文件裝載Product對象和圖像。下面是Product類的代碼:

    package net.blogjava.mobile;
    import java.io.Serializable;
    // 需要序列化的類必須實現Serializable接口
    public class Product implements Serializable
    {
    private String id;
    private String name;
    private float price;
    // 此處省略了屬性的getter和setter方法
     

    在存取數據之前,需要使用下面的代碼創建一個SharedPreferences對象。

    mySharedPreferences = getSharedPreferences("base64",Activity.MODE_PRIVATE);

    其中mySharedPreferences是在類中定義的SharedPreferences類型變量。

    在保存Product對象之前,需要創建Product對象,并將相應組件中的值賦給Product類的相應屬性。將Product對象保存在XML文件中的代碼如下:

    Product product = new Product();
    product.setId(etProductID.getText().toString());
    product.setName(etProductName.getText().toString());
    product.setPrice(Float.parseFloat(etProductPrice.getText().toString()));
    ByteArrayOutputStream baos 
    = new ByteArrayOutputStream();
    ObjectOutputStream oos 
    = new ObjectOutputStream(baos);
    // 將Product對象放到OutputStream中
    oos.writeObject(product);
    mySharedPreferences 
    = getSharedPreferences("base64", Activity.MODE_PRIVATE);
    // 將Product對象轉換成byte數組,并將其進行base64編碼
    String productBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
    SharedPreferences.Editor editor 
    = mySharedPreferences.edit();
    // 將編碼后的字符串寫到base64.xml文件中
    editor.putString("product", productBase64);
    editor.commit();

    保存圖像的方法與保存Product對象的方法類似。由于在保存之前,需要選擇一個圖像,并將該圖像顯示在ImageView組件中,因此,從ImageView組件中可以直接獲得要保存的圖像。將圖象保存在XML文件中的代碼如下:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 將ImageView組件中的圖像壓縮成JPEG格式,并將壓縮結果保存在ByteArrayOutputStream對象中
    ((BitmapDrawable) imageView.getDrawable()).getBitmap().compress(CompressFormat.JPEG, 50, baos);
    String imageBase64 
    = new String(Base64.encodeBase64(baos.toByteArray()));
    // 保存由圖像字節流轉換成的Base64格式字符串
    editor.putString("productImage", imageBase64);
    editor.commit();

        其中compress方法的第2個參數表示壓縮質量,取值范圍是0至100,0表示最高壓縮比,但圖像效果最差,100則恰恰相反。在本例中取了一個中間值50。

        從XML文件中裝載Product對象和圖像是保存的逆過程。也就是從XML文件中讀取Base64格式的字符串,然后將其解碼成字節數組,最后將字節數組轉換成Product和Drawable對象。裝載Product對象的代碼如下:

    String productBase64 = mySharedPreferences.getString("product""");
    // 對Base64格式的字符串進行解碼
    byte[] base64Bytes = Base64.decodeBase64(productBase64.getBytes());
    ByteArrayInputStream bais 
    = new ByteArrayInputStream(base64Bytes);
    ObjectInputStream ois 
    = new ObjectInputStream(bais);
    // 從ObjectInputStream中讀取Product對象
    Product product = (Product) ois.readObject();

    裝載圖像的代碼如下:
    String imageBase64 = mySharedPreferences.getString("productImage","");
    base64Bytes 
    = Base64.decodeBase64(imageBase64.getBytes());
    bais 
    = new ByteArrayInputStream(base64Bytes);
    // 在ImageView組件上顯示圖像
    imageView.setImageDrawable(Drawable.createFromStream(bais,"product_image"));

    在上面的代碼中使用了Drawable類的createFromStream方法直接從流創建了Drawable對象,并使用setImageDrawable方法將圖像顯示在ImageView組件上。

    在 這里需要提一下的是圖像選擇。在本例中使用了res\drawable目錄中的除了icon.png外的其他圖像。為了能列出這些圖像,本例使用了 Java的反射技術來枚舉這些圖像的資源ID。基本原理是枚舉R.drawable類中所有的Field,并獲得這些Field的值。如果采用這個方法, 再向drawable目錄中添加新的圖像,或刪除以前的圖像,并不需要修改代碼,程序就可以顯示最新的圖像列表。枚舉圖像資源ID的代碼如下:
    // 獲得R.drawable類中所有的Field
    Field[] fields = R.drawable.class.getDeclaredFields();
    for (Field field : fields)
    {
    if (!"icon".equals(field.getName()))
    imageResIdList.add(field.getInt(R.drawable.
    class));
    }

        運行本例后,單擊【選擇產品圖像】按鈕,會顯示一個圖像選擇對話框,如圖1所示。選中一個圖像后,關閉圖像選擇對話框,并單擊【保存】按鈕。如果保存成功,將顯示如圖2所示的提示對話框。當再次運行程序后,會顯示上次成功保存的數據。





    查看base64.xml文件,會看到如下的內容:

    <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
    <map>
    <string name="productImage">/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABDsyj7yK3</string>
    <string name="product">rO0ABXNyABtuZXQuYmxvZ2phdmEubW9iaWxlLlByb2</string>
    </map>

        注意:雖然可以采用編碼的方式通過SharedPreferences保存任何類型的數據,但作者并不建議使用SharedPreferences保存尺寸很大的數據。如果讀者要存取更




    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2010-09-08 09:49 銀河使者 閱讀(4063) 評論(5)  編輯  收藏 所屬分類: java 原創移動(mobile) 圖書Android/OPhone

    評論

    # re: 《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據[未登錄]  回復  更多評論   

    PreferenceScreenExt 代碼:




    package asai.cn.seekbardemo;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;

    import android.app.Dialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.SharedPreferences;
    import android.preference.Preference;
    import android.preference.PreferenceGroup;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.View.OnClickListener;
    import android.widget.AdapterView;
    import android.widget.ListView;
    import android.widget.RelativeLayout;
    import android.widget.SimpleAdapter;
    import android.widget.TextView;
    import android.widget.AdapterView.OnItemClickListener;

    public class PreferenceScreenExt extends PreferenceGroup implements
    OnItemClickListener, DialogInterface.OnDismissListener {

    private Dialog dialog;
    private TextView title, summary;
    private SharedPreferences share;
    private RelativeLayout area;
    private ListView listView;
    List<Preference> list;

    private List<HashMap<String, String>> listStr;
    private CharSequence[] mEntries;
    private String mValue;

    public PreferenceScreenExt(Context context, AttributeSet attrs) {
    this(context, attrs, android.R.attr.preferenceScreenStyle);
    // TODO Auto-generated constructor stub
    }

    public PreferenceScreenExt(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, android.R.attr.preferenceScreenStyle);
    // TODO Auto-generated constructor stub
    int resouceId = attrs.getAttributeResourceValue(null, "Entries", 0);
    if (resouceId > 0) {
    mEntries = getContext().getResources().getTextArray(resouceId);
    }
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
    // TODO Auto-generated method stu
    View view = LayoutInflater.from(getContext()).inflate(
    R.layout.preference_screen, null);
    area = (RelativeLayout) view.findViewById(R.id.area);
    share = getPreferenceManager().getSharedPreferences();
    title = (TextView) view.findViewById(R.id.title);
    summary = (TextView) view.findViewById(R.id.summary);
    title.setText(getTitle());
    summary.setText(share.getString(getKey(), getSummary() == null ? ""
    : getSummary().toString()));
    area.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    showDialog();
    }
    });
    return view;
    }

    public void bindView(ListView listview) {
    int length = mEntries.length;
    int i = 0;
    listStr = new ArrayList<HashMap<String, String>>();
    for (i = 0; i < length; i++) {
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("keyname", mEntries[i].toString());
    listStr.add(map);
    }
    SimpleAdapter simple = new SimpleAdapter(getContext(), listStr,
    R.layout.dialog_view, new String[] { "keyname" },
    new int[] { R.id.text });
    listview.setAdapter(simple);
    listview.setOnItemClickListener(this);
    }

    public void showDialog() {
    listView = new ListView(getContext());
    bindView(listView);
    dialog = new Dialog(getContext(), android.R.style.Theme_NoTitleBar);
    dialog.setContentView(listView);
    dialog.setOnDismissListener(this);
    dialog.show();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
    // TODO Auto-generated method stub
    mValue = listStr.get(position).get("keyname").toString();
    SharedPreferences.Editor editor = getEditor();
    editor.putString(getKey(), mValue);
    editor.commit();
    dialog.dismiss();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
    // TODO Auto-generated method stub
    summary.setText(mValue);
    }
    }
    2010-09-25 14:35 | terry

    # re: 《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據[未登錄]  回復  更多評論   

    對應的XML


    preference_screen.xml

    <RelativeLayout android:id="@+id/area" android:gravity="center_vertical"
    android:layout_marginTop="5px" android:clickable="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/row_bg" android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <TextView android:id="@+id/title" android:layout_marginLeft="20dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textSize="35sp" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    </TextView>
    <TextView android:id="@+id/summary"
    android:layout_marginRight="20dp" android:textSize="35sp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:layout_alignParentRight="true" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    </TextView>
    </RelativeLayout>
    2010-09-25 14:35 | terry

    # re: 《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據[未登錄]  回復  更多評論   

    dialog_view.xml


    <LinearLayout android:layout_width="fill_parent"
    android:background="@drawable/row_bg" xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:gravity="center"
    android:layout_height="fill_parent">


    <TextView android:id="@+id/text" android:layout_marginLeft="20dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textSize="35sp" android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    </TextView>


    </LinearLayout>
    2010-09-25 14:36 | terry

    # re: 《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據[未登錄]  回復  更多評論   

    隨便測試的ActivityGroup:


    package asai.cn.seekbardemo;

    import android.app.ActivityGroup;
    import android.app.LocalActivityManager;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.view.Window;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.LinearLayout;

    public class main extends ActivityGroup implements OnClickListener {

    private LocalActivityManager lm;
    private LinearLayout layout;
    private Button btn, btn2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.group);
    lm = getLocalActivityManager();

    layout = (LinearLayout) findViewById(R.id.layout);
    btn = (Button) findViewById(R.id.Button01);
    btn2 = (Button) findViewById(R.id.Button02);

    btn.setOnClickListener(this);
    btn2.setOnClickListener(this);
    Intent intent = new Intent(this, seekBarDemo.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    Window w = lm.startActivity("test", intent);
    View v = w.getDecorView();
    layout.removeAllViews();
    layout.addView(v);
    layout.invalidate();

    }

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()) {
    case R.id.Button01:
    Intent intent = new Intent(this, seekBarDemo.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    Window w = lm.startActivity("test", intent);
    View view = w.getDecorView();
    layout.removeAllViews();
    layout.addView(view);
    break;
    case R.id.Button02:
    Intent in = new Intent(this, test.class);
    in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    Window win = lm.startActivity("ww", in);
    View vw = win.getDecorView();
    layout.removeAllViews();
    layout.addView(vw);
    break;
    default:
    break;
    }
    }
    }
    2010-09-25 14:37 | terry

    # re: 《Android/OPhone開發完全講義》連載(7):使用SharedPreferences存取復雜數據[未登錄]  回復  更多評論   

    還少了個XML配置:
    <asai.cn.seekbardemo.PreferenceScreenExt
    Entries="@array/country" android:title="收音區域" android:summary="美國"
    android:key="eeg">
    </asai.cn.seekbardemo.PreferenceScreenExt>


    數組:
    <string-array name="country">
    <item>美國</item>
    <item>中國</item>
    <item>英國</item>
    </string-array>
    2010-09-25 14:42 | terry
    主站蜘蛛池模板: 亚洲欧美国产日韩av野草社区| 亚洲片一区二区三区| 亚洲色图在线播放| 国产啪精品视频网站免费尤物| 亚洲av片一区二区三区| 窝窝影视午夜看片免费| 亚洲精品视频在线观看你懂的| 日韩免费码中文在线观看| 亚洲综合色视频在线观看| 看亚洲a级一级毛片| 亚洲AV之男人的天堂| 一级做性色a爰片久久毛片免费| 久久久久亚洲AV成人网人人网站| 国产黄色免费观看| 久久精品国产96精品亚洲| 18未年禁止免费观看| 77777午夜亚洲| 日韩特黄特色大片免费视频| 亚洲成a人片在线观看天堂无码| 免费一级毛片在播放视频| 国产精品1024在线永久免费 | 久久久亚洲裙底偷窥综合| 成人免费视频77777| 亚洲AV无码一区二区三区久久精品| 国产在线19禁免费观看| 成人久久久观看免费毛片| 国产亚洲精品线观看动态图| 久久99精品国产免费观看| 亚洲日本国产综合高清| 免费又黄又爽的视频| 毛片免费在线观看| 亚洲一级在线观看| 亚洲男人的天堂一区二区| 午夜免费啪视频在线观看| 亚洲综合一区无码精品| 国产精品亚洲美女久久久| 最近免费中文字幕mv在线电影| 亚洲精品成a人在线观看夫| 亚洲中文字幕无码永久在线 | 久久久久免费精品国产| 亚洲中文字幕无码mv|