یه تابستون متفاوت با یه تصمیم هوشمندانه! دوره هوش مصنوعی با تخفیف ویژه، فقط با کد AI84 دوره هوش مصنوعی با تخفیف ویژه، فقط با کد AI84
🎯 ثبت نام

روش های دیگر ذخیره سازی داده (preferences and files)

این آموزش تمرکز خود را بر شرح نحوه ی ذخیره سازی جفت های کلید-مقدار در فایل های اندروید (File based persistence) با فراخوانی preference API قرار می دهد. سپس چگونگی خواندن/نوشتن فایل در اندروید را تشریح می کند.

آموزش File based persistence (ذخیره داده ها در سیستم فایل)

آموزش روش های ذخیره ی ماندگار داده ها به صورت محلی (local data persistence)

اندروید این امکان را فراهم می آورد تا داده های اپلیکیشن را در سیستم فایل ذخیره نمایید. در واقع سیستم اندروید به ازای هر اپلیکیشن یک پوشه ی data/data/[application package] ایجاد می کند.
اندروید برای ذخیره ی داده ها در سیستم فایل محلی روش های زیر را پشتیبانی می کند:

  • Files – می توان داده ها را در فایل ذخیره کرده و بروز رسانی نمود (روشی قدیمی).
  • Preferences – اندروید به شما اجازه می دهد جفت های کلید-مقدار از نوع داده ای اولیه (primitive data type) را به صورت دائمی ذخیره نمایید (به شما امکان می دهد اطلاعات مربوط به تنظیمات انتخابی کاربر را با استفاده از آبجکت sharedpreferences به صورت کلید-مقدار ذخیره کنید).
  • SQLite database – می توان نمونه یا نسخه های موجود از دیتابیس SQLite حامل داده های اپلیکیشن را در سیستم فایل و به صورت محلی ذخیره کرد (ذخیره ی داده های اپلیکیشن در سیستم مدیریت متحدالشکل دیتابیس که اندروید توسط SQLite پشتیبانی می کند).

فایل ها در پوشه ی files و تنظیمات اپلیکیشن در قالب فایل های XML داخل پوشه ی shared-prefs ذخیره و نگهداری می شوند.
اگر اپلیکیشن شما یک دیتابیس SQLite ایجاد کند، اندروید به صورت پیش فرض این دیتابیس را در دایرکتوری اصلی اپلیکیشن و تحت پوشه ی databases ذخیره می نماید.
تصویر زیر یک سیستم فایل را به نمایش می گذارد که فایل های ساده، فایل های کش شده (cache file) و اطلاعات مربوط به وضعیت تنظیمات انتخابی کاربر (preferences) را شامل می شود.

روش های ذخیره ی ماندگار داده ها به صورت محلی (local data persistence)

تنها اپلیکیشن است که اجازه ی درج داده و نوشتن در پوشه ی اصلی اپلیکیش (app-directory) را دارد. اپلیکیشن همچنین این قابلیت را دارد که زیرپوشه های (sub-directory) لازم را در پوشه ی اصلی (application directory) ایجاد نماید. جهت ایجاد این زیرپوشه ها، اپلیکیشن مورد نظر می تواند مجوزهای لازم در سطح خواندن و نوشتن را به دیگر برنامه ها اعطا کند.

آموزش ذخیره سازی internal داده در مقایسه با ذخیره ی داده ها به صورت external

اندروید دارای دو حافظه ی داخل و خارجی است و داده ها را به صورت internal و external ذخیره می کند. حافظه ی خارجی دارای سطح دسترسی شخصی نبوده (private نیست) و همیشه در دسترس نیست. به عنوان مثال، زمانی که دستگاه اندروید از طریق USB به کامپیوتر وصل می شود، این حافظه ی خارجی به طور موقت از دسترس اپلیکیشن های اندروید خارج می گردد.

آموزش جایگذاری اپلیکیشن در حافظه ی خارجی

از ویرایش 8 مجموعه ابزار ساخت و توسعه ی اپلیکیشن های اندروید (SDK level 8) می توان در فایل تنظیمات (manifest) مشخص نمود که اپلیکیشن مورد نظر امکان نصب بر روی حافظه ی خارجی را داشته باشد یا اینکه اپلیکیشن مزبور بایستی بر روی حافظه ی خارجی جایگذاری شود. برای نیل به این هدف کافی است مقدار android:installLocation را در فایل تنظیمات برابر preferExternal یا auto قرار دهید.
در این شرایط، ممکن است برخی از کامپوننت های نرم افزاری و تشکیل دهنده اپلیکیشن بر روی mount point یا محل ذخیره سازی رمزنگاری شده (encrypted) خارجی جایگذاری شوند. دیتابیس و سایر داده های private (با سطح دسترسی شخصی) همچنان فقط بر روی حافظه ی داخلی سیستم (storage system) ذخیره می شوند.

آموزش Preferences (ذخیره و بازگردانی اطلاعات مربوط به تنظیمات کاربر)

آموزش ذخیره جفت های کلید-مقدار از نوع داده ای اولیه

اندروید با ارائه و پشتیبانی از کلاس SharedPreferences این امکان را مهیا می کند تا جفت های کلید-مقدار از جنس داده ای اولیه را در سیستم فایل اندروید ذخیره نمایید (تنظیمات انتخابی کاربر همچون اندازه ی فونت و رنگ متن که داده های کوچک هستند را به صورت key-value ذخیره نمایید).
Preferences و تنظیمات انتخابی کاربر را می توان به راحتی داخل فایل های منبع XML تعریف نمود.
کلاس PreferenceManager با ارائه ی توابعی به توسعه دهنده این امکان را می دهد تا اطلاعات مربوط به تنظیمات کاربر، مستقر در یک فایل XML را بازیابی کند. کد زیر نحوه ی دسترسی به تنظیمات ذخیره شده در یک فایل XML را به نمایش می گذارد.

1
2
3
# getting preferences from a specified file
SharedPreferences settings = getSharedPreferences("Test", Context.MODE_PRIVATE);
<button></button>

Preferences می بایست به صورت private ویژه ی اپلیکیشن مورد نظر ایجاد شود. تمامی کامپوننت ها و اجزا تشکیل دهنده ی اپلیکیشن می توانند به اطلاعات preferences دسترسی داشته باشند. به اشتراک گذاری اطلاعات با یک اپلیکیشن دیگر که دارای فایل preference سراسری با دسترسی در سطح خواندن و نوشتن (world readable/writable) می باشد، امری است که به ندرت اتفاق می افتد. چرا که در این صورت کامپوننت خارجی می بایست از اسم و محل قرار گیری دقیق فایل مطلع باشد.
Preferences پیش فرض به راحتی با فراخوانی متد PreferenceManager.getDefaultSharedPreferences(this) در اختیار دیگر کامپوننت های اپلیکیشن قرار می گیرد. برای دسترسی به مقدار preference کافی است کلید مربوطه و آبجکتی از کلاس SharedPreferences را مانند زیر مورد استفاده قرار دهید.

1
2
3
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity();
String url = settings.getString("url", "n/a");
<button></button>

به منظور ایجاد و ویرایش مقادیر preferences لازم است متد edit() را بر روی آبجکت SharedPreferences فراخوانی نمایید. پس از ویرایش مقدار، بایستی متد apply() را فراخوانی کنید تا مقادیر جدید به صورت ناهمزمان در سیستم فایل اعمال شوند. لازم به توضیح است که متد commit() تغییرات را به صورت همزمان به فایل سیستم اعمال می کند، از این جهت استفاده از متد مذکور در این سناریو توصیه نمی شود.

1
2
3
4
Editor edit = preferences.edit();
edit.putString("username", "new_value_for_user");
edit.apply();
<button></button>

آموزش گوش فراخوانی به تغییرات در تنظیمات کاربر به وسیله ی preference listener

می توانید با فراخوانی متد registerOnSharedPreferenceChangeListener() بر روی آبجکت SharedPreference به تغییرات در preferences گوش داده و از آن ها مطلع شوید.

1
2
3
4
5
6
7
8
9
10
SharedPreferences prefs =
    PreferenceManager.getDefaultSharedPreferences(this);
// Instance field for listener
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // Your Implementation
  }
};
prefs.registerOnSharedPreferenceChangeListener(listener);
<button></button>

توجه داشته باشید که SharedPreferences تمامی listener یا گوش فراخوان ها را داخل WeakHashMap نگه می دارد، به همین علت چنانچه کد شما اشاره گری به آن تعریف نکرده باشد (آن را داخل متغیر نگه ندارد)، listener ها بازیافت می شوند و اطلاعات مورد نظر شما از دست خواهد رفت.

آموزش: آنچه لازم است

پروژه ی این بخش مبتنی بر نمونه اپلیکیشن "de.vogella.android.socialapp" از آموزش action bar در مباحث قبلی می باشد.

تمرین: آنچه لازم است

برای تمرین زیر لازم است یک پروژه ی اندرویدی به نام com.example.android.rssfeed همراه با یک المان Settings در action bar ایجاد نمایید.

تمرین: ذخیره ی تنظیمات کاربر برای RSSfeed

در تمرین جاری، برنامه را گونه ای می نویسید که یک activity دیگر باز شده و به کاربر این امکان را بدهد تا URL دلخواه خود برای RSS feed را وارد نماید. این activity ظاهر و UI خود را از یک فایل xml که حاوی تنظیمات انتخابی کاربر است (xml preference file)، می خواند.

آموزش ایجاد فایل preference

یک فایل XML به نام mypreferences.xml در پوشه ی XML ایجاد نمایید. المان های زیر را به آن اضافه نمایید.

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8" ?>
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android">
<edittextpreference android:key="url"
                    android:title="Rss feed URL"
                    android:inputtype="textUri" />
<checkboxpreference android:title="Aktiv" android:key="active" />
</preferencescreen>
<button></button>

آموزش ایجاد activity جهت دریافت ورودی از کاربر

ابتدا کلاس SettingsActivity که از PreferenceActivity ارث بری می کند را ایجاد نمایید. این activity فایل preference را بارگذاری نموده و به کاربر اجازه می دهد تا مقادیر را ویرایش کند.

1
2
3
4
5
6
7
8
9
10
11
                    package com.example.android.rssreader;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                addPreferencesFromResource(R.xml.mypreferences);
        }
}
<button></button>

این کلاس را به عنوان یک activity در فایل تنظیمات اپلیکیشن AndroidManifest.xml ثبت و معرفی نمایید.

آموزش متصل کردن activity مربوط به تنظیمات و دریافت ورودی کاربر

Activity مربوط به preference و دریافت تنظیمات دلخواه کاربر را با فراخوانی متد onOptionsItemSelected() باز نمایید.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        return true;
}
// This method is called once the menu is selected
@Override
public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.preferences:
                // Launch settings activity
                Intent i = new Intent(this, SettingsActivity.class);
                startActivity(i);
                break;
                // more code...
        }
        return true;
}
<button></button>

آموزش بارگذاری RSS feed با استفاده از مقدار preference

تکه کد زیر نشان می دهد چگونه می توان از یک متد به مقدار preference دسترسی پیدا کرد.

1
2
3
4
5
// if you use this in a service or activity you can use this
// if you use this in a fragment use getActivity() or getContent() as parameter
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
String url = settings.getString("url", "http://www.vogella.com/article.rss");
<button></button>

آموزش تست اپلیکیشن

اپلیکیشن خود را اجرا نمایید. آیتم (action) Settings را از action bar انتخاب کنید. بایستی یک activity دیگر به نمایش در آمده و شما بتوانید آدرس URL دلخواه را وارد کنید. پس از کلیک بر روی دکمه ی بازگشت (back) و بروز رسانی (refresh)، با بررسی activity اطمینان حاصل کنید که مقدار url در activity بکار برده شده است.

تمرین اضافی: نمایش مقدار جاری در settings

تکه کد زیر نشان می دهد چگونه می توان مقدار جاری را در صفحه ی preference نمایش داد.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.example.android.rssreader;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
public class SettingsActivity extends PreferenceActivity implements
                OnSharedPreferenceChangeListener {
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                addPreferencesFromResource(R.xml.mypreferences);
                // show the current value in the settings screen
                for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
                        initSummary(getPreferenceScreen().getPreference(i));
                }
        }
        @Override
        protected void onResume() {
                super.onResume();
                getPreferenceScreen().getSharedPreferences()
                                .registerOnSharedPreferenceChangeListener(this);
        }
        @Override
        protected void onPause() {
                super.onPause();
                getPreferenceScreen().getSharedPreferences()
                                .unregisterOnSharedPreferenceChangeListener(this);
         }
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
                        String key) {
                updatePreferences(findPreference(key));
        }
        private void initSummary(Preference p) {
                if (p instanceof PreferenceCategory) {
                        PreferenceCategory cat = (PreferenceCategory) p;
                        for (int i = 0; i < cat.getPreferenceCount(); i++) {
                                initSummary(cat.getPreference(i));
                        }
                } else {
                        updatePreferences(p);
                }
        }
        private void updatePreferences(Preference p) {
                if (p instanceof EditTextPreference) {
                        EditTextPreference editTextPref = (EditTextPreference) p;
                        p.setSummary(editTextPref.getText());
                }
        }
}
<button></button>
نمایش مقدار جاری در settings

آموزش File API

آموزش استفاده از File API

برای دسترسی به سیستم فایل می توانید از طریق کلاس های java.io اقدام نمایید. اندروید کلاس های کمکی (helper) در اختیار توسعه دهنده قرار می دهد که ایجاد و دسترسی به فایل ها و پوشه های جدید را آسان می سازد. برای مثال، getDir(String, int) پوشه ی مورد نیاز را ایجاد نموده و دسترسی به آن را فراهم می سازد. متد openFileInput(String s) یک فایل برای ورودی باز کرده و متد openFileOutput(String s, Context.MODE_PRIVATE) نیز یک فایل جدید ایجاد می نماید.
اندروید از فایل های خواندنی و نوشتنی سراسری (world readable/writable) پشتیبانی می کند. اما به طور کلی توصیه می شود دسترسی به فایل ها را فقط به خود اپلیکیشن محدود نمایید (فایل های اپلیکیشن را private نگه دارید) و در صورت نیاز به اشتراک گذاری داده ها بین اپلیکیشن ها از کامپوننت نرم افزاری content provider استفاده کنید.
مثال زیر استفاده از API مورد نظر را به نمایش می گذارد.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Util {
        public static void writeConfiguration(Context ctx ) {
                try (FileOutputStream openFileOutput =
                         ctx.openFileOutput( "config.txt", Context.MODE_PRIVATE);) {
                        openFileOutput.write("This is a test1.".getBytes());
                        openFileOutput.write("This is a test2.".getBytes());
                } catch (Exception e) {
                        // not handled
                }
        }
}
public void readFileFromInternalStorage(String fileName) {
        String eol = System.getProperty("line.separator");
        try (BufferedReader input = new BufferedReader(new InputStreamReader(
                openFileInput(fileName))); ){
          String line;
          StringBuffer buffer = new StringBuffer();
          while ((line = input.readLine()) != null) {
                buffer.append(line + eol);
          }
        } catch (Exception e) {
                 // we do not care
        }
}
<button></button>

آموزش حافظه و محل ذخیره سازی خارجی (external storage)

اندروید از حافظه ی خارجی مانند SD و دسترسی به آن نیز پشتیبانی می کند. تمامی فایل ها و پوشه های مستقر در حافظه ی خارجی برای کلیه ی اپلیکیشن هایی که دارای مجوز لازم هستند، قابل دسترسی می باشد.
جهت خواندن داده از حافظه ی خارجی، اپلیکیشن شما می بایست از مجوز android.permission.READ_EXTERNAL_STORAGE برخوردار باشد.
به منظور درج و نوشتن داده در حافظه ی خارجی، اپلیکیشن شما می بایست از مجوز android.permission.WRITE_EXTERNAL_STORAGE برخوردار باشد. برای دسترسی به حافظه ی خارجی، کافی است متد Environement.getExternalStorageDirectory() را فراخوانی نمایید.
با فراخوانی متد زیر شما می توانید وضعیت حافظه ی خارجی را بررسی کنید. چنانچه دستگاه اندروید از طریق USB به کامپیوتر متصل شده است، در آن صورت کارت SD که به عنوان حافظه خارجی مورد استفاده قرار گرفته است، از دسترس خارج می شود.

1
2
                    Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
<button></button>

تکه کد زیر مثالی از خواندن اطلاعات از حافظه ی خارجی را به نمایش می گذارد.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
private void readFileFromSDCard() {
        File directory = Environment.getExternalStorageDirectory();
        // assumes that a file article.rss is available on the SD card
        File file = new File(directory + "/article.rss");
        if (!file.exists()) {
                throw new RuntimeException("File not found");
        }
        Log.e("Testing", "Starting to read");
        BufferedReader reader = null;
        try {
                reader = new BufferedReader(new FileReader(file));
                StringBuilder builder = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                        builder.append(line);
                }
        } catch (Exception e) {
                e.printStackTrace();
        } finally {
                if (reader != null) {
                        try {
                                reader.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
        }
}
<button></button>
1395/12/05 9867 2218
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...