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

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

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

    隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
    數(shù)據(jù)加載中……

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

    本文為《Android/OPhone開發(fā)完全講義》一書的內(nèi)容連載。轉(zhuǎn)載請(qǐng)注明出處

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

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

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

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

        在本例中將一個(gè)Product類的對(duì)象實(shí)例和一個(gè)圖像保存在XML文件中,并在程序重新運(yùn)行后從XML文件裝載Product對(duì)象和圖像。下面是Product類的代碼:

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

    在存取數(shù)據(jù)之前,需要使用下面的代碼創(chuàng)建一個(gè)SharedPreferences對(duì)象。

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

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

    在保存Product對(duì)象之前,需要?jiǎng)?chuàng)建Product對(duì)象,并將相應(yīng)組件中的值賦給Product類的相應(yīng)屬性。將Product對(duì)象保存在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對(duì)象放到OutputStream中
    oos.writeObject(product);
    mySharedPreferences 
    = getSharedPreferences("base64", Activity.MODE_PRIVATE);
    // 將Product對(duì)象轉(zhuǎn)換成byte數(shù)組,并將其進(jìn)行base64編碼
    String productBase64 = new String(Base64.encodeBase64(baos.toByteArray()));
    SharedPreferences.Editor editor 
    = mySharedPreferences.edit();
    // 將編碼后的字符串寫到base64.xml文件中
    editor.putString("product", productBase64);
    editor.commit();

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

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

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

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

    String productBase64 = mySharedPreferences.getString("product""");
    // 對(duì)Base64格式的字符串進(jìn)行解碼
    byte[] base64Bytes = Base64.decodeBase64(productBase64.getBytes());
    ByteArrayInputStream bais 
    = new ByteArrayInputStream(base64Bytes);
    ObjectInputStream ois 
    = new ObjectInputStream(bais);
    // 從ObjectInputStream中讀取Product對(duì)象
    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方法直接從流創(chuàng)建了Drawable對(duì)象,并使用setImageDrawable方法將圖像顯示在ImageView組件上。

    在 這里需要提一下的是圖像選擇。在本例中使用了res\drawable目錄中的除了icon.png外的其他圖像。為了能列出這些圖像,本例使用了 Java的反射技術(shù)來枚舉這些圖像的資源ID。基本原理是枚舉R.drawable類中所有的Field,并獲得這些Field的值。如果采用這個(gè)方法, 再向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));
    }

        運(yùn)行本例后,單擊【選擇產(chǎn)品圖像】按鈕,會(huì)顯示一個(gè)圖像選擇對(duì)話框,如圖1所示。選中一個(gè)圖像后,關(guān)閉圖像選擇對(duì)話框,并單擊【保存】按鈕。如果保存成功,將顯示如圖2所示的提示對(duì)話框。當(dāng)再次運(yùn)行程序后,會(huì)顯示上次成功保存的數(shù)據(jù)。





    查看base64.xml文件,會(huì)看到如下的內(nèi)容:

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

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




    Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺(tái)灣)

    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) 評(píng)論(5)  編輯  收藏 所屬分類: java 原創(chuàng)移動(dòng)(mobile) 圖書Android/OPhone

    評(píng)論

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

    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開發(fā)完全講義》連載(7):使用SharedPreferences存取復(fù)雜數(shù)據(jù)[未登錄]  回復(fù)  更多評(píng)論   

    對(duì)應(yīng)的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開發(fā)完全講義》連載(7):使用SharedPreferences存取復(fù)雜數(shù)據(jù)[未登錄]  回復(fù)  更多評(píng)論   

    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開發(fā)完全講義》連載(7):使用SharedPreferences存取復(fù)雜數(shù)據(jù)[未登錄]  回復(fù)  更多評(píng)論   

    隨便測(cè)試的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開發(fā)完全講義》連載(7):使用SharedPreferences存取復(fù)雜數(shù)據(jù)[未登錄]  回復(fù)  更多評(píng)論   

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


    數(shù)組:
    <string-array name="country">
    <item>美國</item>
    <item>中國</item>
    <item>英國</item>
    </string-array>
    2010-09-25 14:42 | terry
    主站蜘蛛池模板: 日韩吃奶摸下AA片免费观看| 日本视频免费观看| 亚洲第一网站免费视频| 亚洲电影免费在线观看| 亚洲国产精品嫩草影院在线观看 | 亚洲欧洲免费无码| h片在线免费观看| 无码区日韩特区永久免费系列| 美丽的姑娘免费观看在线播放| 97久久免费视频| 国产四虎免费精品视频| 1024免费福利永久观看网站| av免费不卡国产观看| 无人影院手机版在线观看免费 | a级男女仿爱免费视频| 少妇性饥渴无码A区免费| 国产成人精品无码免费看| 最近2019免费中文字幕6| 日本片免费观看一区二区| 无码人妻久久一区二区三区免费丨| 免费一本色道久久一区| 国产大片51精品免费观看| 亚洲精品乱码久久久久久不卡| 国产精品亚洲mnbav网站 | 免费看美女被靠到爽| 无码国产亚洲日韩国精品视频一区二区三区| 亚洲AⅤ永久无码精品AA| 亚洲人成影院在线观看| 好看的亚洲黄色经典| 亚洲天堂一区二区三区四区| 精品亚洲456在线播放| 国产精品亚洲色图| 中文字幕在线免费视频| 6080午夜一级毛片免费看| 韩国二级毛片免费播放| 亚洲精品老司机在线观看| 亚洲成a人片在线观看中文动漫| 亚洲一区二区三区免费在线观看| 亚洲av成人中文无码专区| 巨胸喷奶水www永久免费| 99re6在线视频精品免费下载|