亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android系統(tǒng)的五種數(shù)據(jù)存儲(chǔ)形式實(shí)例(二)

 更新時(shí)間:2016年12月08日 11:53:45   作者:huang502  
Android系統(tǒng)有五種數(shù)據(jù)存儲(chǔ)形式,分別是文件存儲(chǔ)、SP存儲(chǔ)、數(shù)據(jù)庫(kù)存儲(chǔ)、contentprovider 內(nèi)容提供者、網(wǎng)絡(luò)存儲(chǔ)。本文介紹了Android系統(tǒng)的五種數(shù)據(jù)存儲(chǔ)形式,有興趣的可以了解一下。

之前介紹了Android系統(tǒng)下三種數(shù)據(jù)存儲(chǔ)形式,http://chabaoo.cn/article/99468.htm。今天補(bǔ)充介紹另外兩種,分別是內(nèi)容提供者和網(wǎng)絡(luò)存儲(chǔ)。有些人可能認(rèn)為內(nèi)存提供者和網(wǎng)絡(luò)存儲(chǔ)更偏向于對(duì)數(shù)據(jù)的操作而不是數(shù)據(jù)的存儲(chǔ),但這兩種方式確實(shí)與數(shù)據(jù)有關(guān),所以這里還是將這兩種形式簡(jiǎn)要的說(shuō)明一下。

 Content Provider:

Content Provider,中文名是內(nèi)存提供者,Android四大組件之一,內(nèi)容提供者是應(yīng)用程序之間共享數(shù)據(jù)的接口,以數(shù)據(jù)庫(kù)形式存入手機(jī)內(nèi)存,可以共享自己的數(shù)據(jù)給其他應(yīng)用使用。之所以需要設(shè)計(jì)一個(gè)單獨(dú)的控件來(lái)操作數(shù)據(jù),是為了實(shí)現(xiàn)應(yīng)用程序之間的數(shù)據(jù)傳遞。通過(guò)查看DDMS中的目錄結(jié)構(gòu)可以看出,數(shù)據(jù)庫(kù)文件對(duì)于其他應(yīng)用來(lái)說(shuō)是不可讀、不可寫(xiě),而日常生活中又需要獲取其他應(yīng)用的數(shù)據(jù),尤其是系統(tǒng)自帶軟件的數(shù)據(jù)。比如打開(kāi)QQ或者微信時(shí)會(huì)提示是否同步聯(lián)系人,又比如備份短信的時(shí)候,這些都需要訪問(wèn)和操作其他應(yīng)用的數(shù)據(jù)庫(kù)。因此谷歌工程師在底層軟件中集成了大量的方法利用內(nèi)存提供者的原理,類似于在數(shù)據(jù)庫(kù)中提供一個(gè)對(duì)外訪問(wèn)的路徑,供其他應(yīng)用訪問(wèn)。

為了更好的理解內(nèi)存提供者的工作原理,可以自定義一個(gè)內(nèi)容提示者來(lái)幫助理解。首先寫(xiě)一個(gè)類繼承ContentProvider,實(shí)現(xiàn)該類中的方法,包括一些增刪改查和數(shù)據(jù)初始化的方法,可以在方法中實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的增刪改查操作。數(shù)據(jù)庫(kù)本來(lái)是不對(duì)外開(kāi)放的,所以為保護(hù)數(shù)據(jù),類中的方法原始返回?cái)?shù)據(jù)均是空類型。為保證數(shù)據(jù)的安全性,可以創(chuàng)建一個(gè)UriMatcher對(duì)象,利用addURIf方法添加Uri的路徑規(guī)則,在每一次進(jìn)行數(shù)據(jù)操作時(shí)先判斷傳入的路徑是否符合命名規(guī)則。使用內(nèi)存提供者需要在配置文件中添加provider標(biāo)簽,指定主機(jī)名。只有當(dāng)訪問(wèn)者與內(nèi)容提供者的主機(jī)名一致時(shí),才可以建立數(shù)據(jù)連接。在另一個(gè)應(yīng)用中實(shí)現(xiàn)對(duì)內(nèi)存提供者的訪問(wèn)。具體操作是:創(chuàng)建內(nèi)容提供者解析器,定義要訪問(wèn)的Uri的路徑。Uri路徑有著固定的格式:”content://主機(jī)名/匹配字符”。 利用內(nèi)容提供者解析器進(jìn)行增刪改查,和要操作的數(shù)據(jù)庫(kù)之間建立聯(lián)系。以上內(nèi)容通常用來(lái)理解內(nèi)容提供者的工作原理,實(shí)際工作中很少用到自定義的內(nèi)容提示者。實(shí)際中用的比較多的是用內(nèi)容提供者操作系統(tǒng)聯(lián)系人、系統(tǒng)短信等系統(tǒng)應(yīng)用的數(shù)據(jù)庫(kù)。

內(nèi)容提供者操作系統(tǒng)應(yīng)用時(shí)相對(duì)簡(jiǎn)單,需要用到的大部分程序已經(jīng)在底層實(shí)現(xiàn),要做的是調(diào)用各種方法和相關(guān)的參數(shù)。需要關(guān)注的參數(shù)有Uri路徑、數(shù)據(jù)庫(kù)的表單結(jié)構(gòu)??梢酝ㄟ^(guò)查看底層的代碼獲取相應(yīng)的參數(shù)。其中有些常用的參數(shù)可以記下來(lái),方便調(diào)用。比如獲取全部短信的Uri路徑是: content://sms。與聯(lián)系人有關(guān)的數(shù)據(jù)庫(kù)表單有三個(gè)raw_contacts、data、mimetypes。操作raw_contacts 表的Uri是: content://com.android.contacts/raw_contacts,操作data 表的Uri是:content://com.android.contacts/data。本文以短信的備份、還原來(lái)演示利用內(nèi)容提供者訪問(wèn)短信數(shù)據(jù)庫(kù)。

 先看一下短信和手機(jī)聯(lián)系人有關(guān)的數(shù)據(jù)庫(kù)所在的路徑。短信在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.telephony/databases/目錄,聯(lián)系人在Android 模擬器下存放在的路徑是:/data/data/com.android.providers.contacts/databases/目錄。對(duì)于短信數(shù)據(jù)庫(kù)我們關(guān)心的表數(shù)據(jù)有:address、type、body、date,分別表示發(fā)送者號(hào)碼、短信類型(收還是發(fā))、短信內(nèi)容、日期。對(duì)于聯(lián)系人數(shù)據(jù)庫(kù)的三張表一定要按照一定的順序依次查找才能得到相關(guān)的數(shù)據(jù),在這不做解釋。盡管開(kāi)發(fā)的時(shí)候不需要了解短信和手機(jī)聯(lián)系人的數(shù)據(jù)庫(kù)路徑,但是要明白短信和手機(jī)聯(lián)系人的數(shù)據(jù)是存在數(shù)據(jù)庫(kù)中的,同時(shí)數(shù)據(jù)庫(kù)對(duì)外是不開(kāi)放的。

與短信有關(guān)的數(shù)據(jù)庫(kù)的目錄結(jié)構(gòu):

本文給出的案例是短信的備份和還原,從而實(shí)現(xiàn)對(duì)系統(tǒng)應(yīng)用數(shù)據(jù)庫(kù)的操作。首先利用內(nèi)容提供者查詢到短信數(shù)據(jù)庫(kù)里的詳細(xì)參數(shù),將該數(shù)據(jù)以Xml文件的形式存入到指定的文件夾。利用xml解析得到數(shù)據(jù),將獲取的數(shù)據(jù)存在一個(gè)工具類中,這樣就能用ListView將數(shù)據(jù)顯示在界面上。具體實(shí)現(xiàn)如下。

package com.example.contentprovider; 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.util.ArrayList;

import java.util.List;

 

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlSerializer;

 

import android.app.Activity;

import android.content.ContentResolver;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.util.Log;

import android.util.Xml;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

/**

 * 短信的備份和還原

 * 添加寫(xiě)短信和讀短信的權(quán)限

 * <uses-permission android:name="android.permission.READ_SMS"/>

  <uses-permission android:name="android.permission.WRITE_SMS"/>

 * @author Huang

 */

 public class MainActivity extends Activity {

  private static final String TAG = "MainActivity";

  private ListView lv;

  private List<Person> mlist;

  private Myadpter adapter;

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    lv = (ListView) findViewById(R.id.lv);

    datafresh();

  }

  //數(shù)據(jù)刷新,一般用到ListView時(shí)最好記得刷新數(shù)據(jù)否則不顯示

  public void datafresh(){

    mlist = getList();

    if(adapter == null){

      adapter = new Myadpter();

    }else {

      adapter.notifyDataSetChanged();

    }

  }

  //用ListView顯示短信內(nèi)容

  public class Myadpter extends BaseAdapter{

    public int getCount() {

      // TODO Auto-generated method stub

      return mlist.size();

    }

    public Object getItem(int position) {

      // TODO Auto-generated method stub

      return null;

    }

    public long getItemId(int position) {

      // TODO Auto-generated method stub

      return 0;

    }

    public View getView(int position, View convertView, ViewGroup parent) {

      TextView tv = new TextView(MainActivity.this);

      tv.setText(mlist.get(position).toString());

      return tv;

    }

  }

  //短信備份 

  public void bankup(View view){

    ContentResolver resolver = getContentResolver();

    Uri uri = Uri.parse("content://sms");

    Cursor cursor = resolver.query(uri, new String[]{"address","body","type","date"}, null, null, null);

    while(cursor.moveToNext()){

      String address = cursor.getString(0);

      String body = cursor.getString(1);

      String type = cursor.getString(2);

      String date = cursor.getString(3);

      //序列化,把短信以Xml文件的形式存儲(chǔ)

      XmlSerializer serializer = Xml.newSerializer();

      File file = new File(getFilesDir(),"info.xml");

      try {

        FileOutputStream fos = new FileOutputStream(file);

        serializer.setOutput(fos, "utf-8");

        serializer.startDocument("utf-8", true);

        serializer.startTag(null, "person");

         

        serializer.startTag(null, "address");

        serializer.text(address);

        serializer.endTag(null, "address");

         

        serializer.startTag(null, "body");

        serializer.text(body);

        serializer.endTag(null, "body");

         

        serializer.startTag(null, "type");

        serializer.text(type);

        serializer.endTag(null, "type");

         

        serializer.startTag(null, "date");

        serializer.text(date);

        serializer.endTag(null, "date");

         

        serializer.endTag(null, "person");

        serializer.endDocument();

        fos.close();

//       Toast.makeText(this, "數(shù)據(jù)保存成功", 0).show();

      } catch (Exception e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

    }

  }

 

  public void restore(View view){

    datafresh();

    lv.setAdapter(adapter);

  }

  //利用Xml解析得到短信內(nèi)容

  private List<Person> getList() {

    ContentResolver resolver = getContentResolver();

    List<Person> list = new ArrayList();//創(chuàng)建一個(gè)Person類存儲(chǔ)標(biāo)簽內(nèi)容

    Person p = new Person();

    File file = new File(getFilesDir(),"info.xml");

    XmlPullParser pullParser = Xml.newPullParser();

    try {

      FileInputStream fis = new FileInputStream(file);

      pullParser.setInput(fis, "utf-8");

      int mtype = pullParser.getEventType();

      while(mtype != XmlPullParser.END_DOCUMENT){

        String name = pullParser.getName();

        switch (mtype){

        case XmlPullParser.START_TAG:

          if("address".equals(name)){

            String address = pullParser.nextText();

            p.setAddress(address);

          }else if("body".equals(name)){

            String body = pullParser.nextText();

            p.setBody(body);

          }else if("type".equals(name)){

            String type = pullParser.nextText();

            p.setType(type);

          }else if("date".equals(name)){

            String date = pullParser.nextText();

            p.setDate(date);

          }

          break;

        case XmlPullParser.END_TAG:

          if("person".equals(name)){

            list.add(p);

          }

          break;

        }

        mtype = pullParser.next();

      }

      Log.i(TAG, list.toString());

      return list;

    } catch (Exception e) {

      // TODO Auto-generated catch block

      e.printStackTrace();

      return null;

    }

  }

} 

效果演示,我的虛擬機(jī)中只存了一條短信:

網(wǎng)絡(luò)存儲(chǔ):

網(wǎng)絡(luò)存儲(chǔ)是最容易理解的一種存儲(chǔ)方式了。其實(shí)說(shuō)簡(jiǎn)單點(diǎn)就是文件的上傳和下載。經(jīng)常聽(tīng)到的云備份就是這種形式。優(yōu)勢(shì)也很明顯,即把數(shù)據(jù)存儲(chǔ)到服務(wù)器,不存儲(chǔ)在本地,使用的時(shí)候直接從網(wǎng)絡(luò)獲取,避免了手機(jī)端信息丟失以及其他的安全隱患。因此,對(duì)于這種形式就不作多的解釋,直接給出一個(gè)文件的上傳和下載的實(shí)例來(lái)演示網(wǎng)絡(luò)存儲(chǔ)。

代碼實(shí)現(xiàn):

package com.example.upload;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.Header;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {
  protected static final int SUCCESS = 1;
  protected static final int ERORR = 2;
  private EditText et_path;
  private ImageView iv;
  //訪問(wèn)網(wǎng)絡(luò)操作耗時(shí),需要在子線程中加一個(gè)代理
  private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
      switch (msg.what) {
      case SUCCESS:
        Bitmap bm = (Bitmap) msg.obj;
        iv.setImageBitmap(bm);
        break;
      case ERORR:
        Toast.makeText(MainActivity.this, "圖片獲取失敗", 0).show();
        break;
      }
      super.handleMessage(msg);
    }};
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    et_path = (EditText) findViewById(R.id.et_path);
    iv = (ImageView) findViewById(R.id.iv);
  }
  //上傳程序
  public void upload(View view){
//    String path = et_path.getText().toString().trim();
//    這里為方便把路徑寫(xiě)死,這種方式不太正規(guī),一般可以讀et_path來(lái)訪問(wèn)
    String path = "/mnt/sdcard/info.txt";
    if(TextUtils.isEmpty(path)){
      Toast.makeText(this, "路徑不能為空", 0).show();
      return;
    }
    File file = new File(path);
    AsyncHttpClient client = new AsyncHttpClient();
    RequestParams param = new RequestParams();
    try {
      param.put("file", file);
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    client.post("http://192.168.1.114:8080/",param, new AsyncHttpResponseHandler() {
      
      @Override
      public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
        // TODO Auto-generated method stub
        Toast.makeText(MainActivity.this, "提交成功", 0).show();
      }
      
      @Override
      public void onFailure(int statusCode, Header[] headers,
          byte[] responseBody, Throwable error) {
        // TODO Auto-generated method stub
        Toast.makeText(MainActivity.this, "提交失敗", 0).show();
      }
    });
  }

  //下載程序  
  public void download(View view){
    new Thread(){
      public void run() {
        try {
          //這里為方便把路徑寫(xiě)死,可以讀et_path來(lái)訪問(wèn),兩者結(jié)果一樣
          URL url = new URL("http://192.168.1.114:8080/demo1.png");
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
          conn.setConnectTimeout(5000);
          conn.setRequestMethod("GET");
          int code = conn.getResponseCode();
          if(code == 200){
            InputStream is = conn.getInputStream();
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            Message msg = Message.obtain();
            msg.what = SUCCESS;
            msg.obj = bitmap;
            handler.sendMessage(msg);
            is.close();
          }
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
           Message msg = Message.obtain();
           msg.what = ERORR;
           handler.sendMessage(msg);
        }
      };
    }.start();
  }
}

至此五種數(shù)據(jù)存儲(chǔ)全部實(shí)現(xiàn)。當(dāng)然,實(shí)際開(kāi)發(fā)中可能比這更復(fù)雜,會(huì)嵌入到別的知識(shí)點(diǎn)中,但數(shù)據(jù)操作無(wú)疑是最為基本的一步,是整體項(xiàng)目開(kāi)發(fā)的基礎(chǔ)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程實(shí)現(xiàn)自定義ProgressBar樣式示例(背景色及一級(jí)、二級(jí)進(jìn)度條顏色)

    Android編程實(shí)現(xiàn)自定義ProgressBar樣式示例(背景色及一級(jí)、二級(jí)進(jìn)度條顏色)

    這篇文章主要介紹了Android編程實(shí)現(xiàn)自定義ProgressBar樣式功能,涉及針對(duì)背景色及一級(jí)、二級(jí)進(jìn)度條顏色的操作技巧,需要的朋友可以參考下
    2017-01-01
  • android通過(guò)led實(shí)現(xiàn)手電筒功能

    android通過(guò)led實(shí)現(xiàn)手電筒功能

    這篇文章主要為大家詳細(xì)介紹了android通過(guò)led實(shí)現(xiàn)手電筒功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • WebView的介紹與簡(jiǎn)單實(shí)現(xiàn)Android和H5互調(diào)的方法

    WebView的介紹與簡(jiǎn)單實(shí)現(xiàn)Android和H5互調(diào)的方法

    這篇文章主要給大家介紹了關(guān)于WebView與簡(jiǎn)單實(shí)現(xiàn)Android和H5互調(diào)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • Android三種網(wǎng)絡(luò)通訊方式及Android的網(wǎng)絡(luò)通訊機(jī)制

    Android三種網(wǎng)絡(luò)通訊方式及Android的網(wǎng)絡(luò)通訊機(jī)制

    在android平臺(tái)目前提供了三種網(wǎng)絡(luò)接口可以使用:分別是java.net.*(標(biāo)準(zhǔn)Java接口)、Org.apache接口和Android.net.*(Android網(wǎng)絡(luò)接口),本文主要給大家介紹android三種網(wǎng)絡(luò)通訊方式及android的網(wǎng)絡(luò)通訊機(jī)制,小伙伴們一起學(xué)習(xí)吧
    2015-11-11
  • Android Git submodule詳解用法示例

    Android Git submodule詳解用法示例

    項(xiàng)目中經(jīng)常會(huì)使用到第三方的 git 庫(kù), 將三方庫(kù)整合到項(xiàng)目中最簡(jiǎn)單的辦法就是復(fù)制粘貼, 但是如果這個(gè)庫(kù)升級(jí)了一個(gè)很酷炫的功能, 你要怎么整合進(jìn)來(lái)呢?(其實(shí)就是 git 版的包管理器)這就是本次要介紹的 git-submodule 操作, 直接把第三方的版本庫(kù)合并到自己的庫(kù)中
    2021-11-11
  • Android ImageView的selector效果實(shí)例詳解

    Android ImageView的selector效果實(shí)例詳解

    這篇文章主要介紹了Android ImageView的selector效果實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Flutter實(shí)現(xiàn)矩形取色器的封裝

    Flutter實(shí)現(xiàn)矩形取色器的封裝

    這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)矩形取色器的封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Flutter本地存儲(chǔ)之基本的鍵值對(duì)存儲(chǔ)詳解

    Flutter本地存儲(chǔ)之基本的鍵值對(duì)存儲(chǔ)詳解

    在原生的?Android?或?iOS?中,都提供了基本的鍵值對(duì)存儲(chǔ)方式,在?Flutter?中,提供了?shared_preferences?這個(gè)插件來(lái)實(shí)現(xiàn)本地鍵值對(duì)數(shù)據(jù)存儲(chǔ),本文就來(lái)和大家簡(jiǎn)單聊聊吧
    2023-03-03
  • 詳解Android Lint的原理及其使用

    詳解Android Lint的原理及其使用

    這篇文章主要介紹了詳解Android Lint的原理及其使用,想了解Lint的同學(xué),一定要著重看一下
    2021-04-04
  • Android學(xué)習(xí)筆記(二)之電話撥號(hào)器

    Android學(xué)習(xí)筆記(二)之電話撥號(hào)器

    目前手機(jī)市場(chǎng)上android已經(jīng)具有強(qiáng)大的霸主地位,吸引了很多的追棒者,android學(xué)習(xí)越來(lái)越火熱,本文給大家介紹android學(xué)習(xí)筆記(二)之電話撥號(hào)器,感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11

最新評(píng)論