یوشا آل ایوب

وبگاه دست نوشته ها و تجربیات شخصی

یوشا آل ایوب

وبگاه دست نوشته ها و تجربیات شخصی

یوشا آل ایوب

دکتر مصطفی چمران: می گویند تقوا از تخصص لازمتر است، آنرا می پذیرم، اما می گویم: آنکس که تخصص ندارد و کاری را می پذیرد، بی تقواست!

تبلیغات
Blog.ir بلاگ، رسانه متخصصین و اهل قلم، استفاده آسان از امکانات وبلاگ نویسی حرفه‌ای، در محیطی نوین، امن و پایدار bayanbox.ir صندوق بیان - تجربه‌ای متفاوت در نشر و نگهداری فایل‌ها، ۳ گیگا بایت فضای پیشرفته رایگان Bayan.ir - بیان، پیشرو در فناوری‌های فضای مجازی ایران
بایگانی

در ادامه مقاله قبلیم که شماره دو "نکات و اصول مهم در برنامه نویسی Java/Android" بود، در این مقاله شماره سه همین موضوع رو ارائه میدم...

 

1- با اضافه کردن خاصیت android:supportsRtl="true" در تگ application فایل AndroidManifiest.xml، مشکل راست به چپ صفحات preferences تون حل خواهد شد. (برای اندروید 4.2 به بعد)

 

2- آیا میدونید هیچ تفاوتی بین fill_parent و match_parent در خاصیت عناصر گرافیکی وجود نداره و هر دو دارای مقدار 1- هستند؟

این مسئله فقط یک تغییر نام جزیی بوده که از API 8 به بعد صورت گرفته و پیشنهاد شده که از match_parent استفاده بشه.

 

3- از اونجایی که SharedPreference ها عملیات read/write برروی دیسک انجام میدن و معمولاً هم در متد OnCreate() یا OnResume() فراخوانی و load می شن، پس بهتره در thread غیر از UI اعمال بشن، تا برنامه رو دچار وقفه نکنن.

همچنین لازم نیست نگران تعدد عملیات باشید، چراکه SharedPreference یک شی Singleton هست و فقط یکبار بارگذاری میشه.

4- در بیشتر مواقع با استفاده از عبارات زیر در تعاریف HttpURLConnection تون، خطای recvfrom failed: ECONNRESET (Connection reset by peer) برطرف خواهد شد:

System.setProperty("http.keepAlive", "false");
myHttpUrlConnection.setRequestProperty("connection", "close");

 

5- برای حل مشکل GC overhead limit exceeded در برنامه Eclipse کافیه ظرفیت حافظه Heap این برنامه رو در فایل eclipse.ini تغییر بدید:

-XX:MaxPermSize=1024m
-Xms512m
-Xmx1024m

 

6- نکته جزیی: آیا میدونید کال بک onCancel() فقط توسط دستور cancel() صدا زده میشه؟

 

7- با استفاده از تگ <include> قادر خواهید بود از طراحی Layout های تکراری اجتناب کنید، و Layout های مشترک/تکراری رو re-use کنید!

 

8- فراموش نکنید که ViewHolder خلاصه ترین و بهترین گزینه برای هندل کردن عناصر گرافیکی ListView هستش.

 

9- آیا میدونید مقدار DEBUG در فایل BuildConfig.java تنها زمانی false میشه که برنامه بصورت Signed Application Package کامپایل/export بشه؟

راه ساده برای اطلاع رسانی:

if (<MY-PACKAGE-NAME>.BuildConfig.DEBUG)
{
   Log.wtf(LOG_TAG, "DEBUG-MODE IS ONE!");
}

نکته: این فایل Build.Config.java بصورت خودکار تولید و در مسیر /gen/<MY-PACKAGE-NAME>/BuildConfig.java قرار داره.

 

10- اگر در برنامه Eclipse هنگام Run پروژه با پیام Warning: Activity not started, its current task has been brought to the front مواجه شدید، کافیه که پروژه رو Clean یا Refresh کرده و مجدداً Run کنید. (Menu -> Project -> Clean)

 

11- آیا میدونید در HttpURLConnection باید redirect ها رو بصورت دستی هندل کنید؟

به این صورت که ابتدا کد header ارسال شده از طرف سرور رو توسط getResponseCode بررسی می کنید، اگر با HTTP_MOVED_TEMP یا HTTP_MOVED_PERM یا HTTP_SEE_OTHER برابر بود، توسط getHeaderField محتوای فیلد Location و Set-Cookie رو بازیابی می کنید و مجدداً درخواست دیگه ای با URL جدید بهمراه کوکی ارسال می کنید.

 

12- آیا می دونید هنگامی که دستگاه با وضعیت low internal storage space مواجه میشه، اندروید بصورت خودکار cache برنامه ها رو(بدون اطلاع رسانی) پاک میکنه؟

 

13- (بطور پیشفرض) اگر برنامه ای رو از طریق صفحه Home باز کنید، اکتیویتی Main برنامه بازمیشه، درصورتی که اگر همون برنامه رو از طریق صفحه Recent apps باز کنید، آخرین اکتیویتی که درش حضور داشتید باز میشه. (در اندروید 2 به بعد)

 

14- نکته جزیی برای API 17 به قبل: به دلایل امنیتی، گوگل پیشنهاد کرده که در حین کار با دستور getSharedPreferences، از حالت MODE_PRIVATE استفاده کنید.

چرا؟ چون این حالت تعیین می کنه فقط برنامه ای که اون preference رو ساخته بتونه بهش دسترسی داشته باشه، و نه دیگر برنامه ها.

MODE_PRIVATE: File creation mode: the default mode, where the created file can only be accessed by the calling application (or all applications sharing the same user ID).

نکته: این فایل preference بطور پیشفرض در مسیر /data/data/<YOUR-PACKAGE-NAME>/shared_prefs/ دستگاه تون قرار داره.

 

15- نکته جزیی: SharedPreference ها برای ذخیره تنظیمات برنامه هستند، و نه ذخیره data ی برنامه!

 

16- SharedPreferences.commit() یا SharedPreferences.apply() ؟

apply: در اندروید 2.3 به بعد تعبیه شده، هیچ return ای بعد از انجام عملیات نداره(چه failure بشه چه success)، کمی سریعتر از commit هستش، داده ها رو بصورت asynchronously ذخیره میکنه(thread ش رو قفل نمی کنه)، اطلاعات رو سریعاً در RAM ثبت میکنه و بعد روی دیسک ذخیره میکنه و...

commit: در همه نسخ اندروید وجود داره، مقدار return ش نسبت به failure/success شدن boolean هستش، کمی کندتر از apply هستش، داده ها رو بصورت synchronously ذخیره میکنه(thread ش رو قفل می کنه)، اطلاعات رو مستقیماً برروی دیسک ذخیره میکنه و بهتره بکمک multi-threading طراحی بشه...

 

17- یک تابع پیشنهادی بهبود یافته برای استفاده از دستورات commit/apply:

public static final void iCommit(final SharedPreferences.Editor editor)
{
   if (Build.VERSION.SDK_INT >= 9) // Gingerbread
   {
      editor.apply();
   }
   else
   {
      new Thread()
      {
         @Override
         public void run()
         {
            editor.commit();
         }
      }.start();
   }
}

 

18- فراموش نکنید برای استفاده از اینترفیس OnSharedPreferenceChangeListener و کال بک onSharedPreferenceChanged() باید shared preferences رو در متد OnResume() و OnPause() ثبت کنید:

@Override
protected final void onResume()
{
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    super.onResume(); // Call at last.
}

@Override
protected final void onPause()
{
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    super.onPause(); // Call at last.
}

 

19- دقت کنید که کاربرد و رفتار اینترفیس OnPreferenceChangeListener با OnSharedPreferenceChangeListener متفاوته!

اینترفیس OnPreferenceChangeListener زمانی فعال میشه که تغییری در کلیدش صورت بگیره(یک کلید)، اما OnSharedPreferenceChangeListener زمانی فعال میشه که تغییری در کل SharedPreference صورت بگیره... همچنین برای استفاده از کال بک OnPreferenceChangeListener باید کلید رو توسط findPreference ثبت کنید تا بتونه رویدادها رو شنود کنه.

 

20- در بیشتر مواقع دلیل رخداد اثتثنای NoClassDefFoundError android.os.AsyncTask باگیه که در Google Play Service وجود داره و بسادگی با روش زیر قابل حله:

try
{
    Class.forName("android.os.AsyncTask"); // Fix AsyncTask bug.
}
catch (final ClassNotFoundException exception)
{

}

 

21- دیده شده در خیلی از برنامه ها برای قراردادن فضاهای Blank در layout برنامه، از عنصر TextView یا حتی LinearLayout استفاده شده! در صورتی که باید از عنصر <View> یا <Space> (برای API 14 به بعد) استفاده بشه، اون هم به این شکل:

برای اندروید های 2 به بعد
<View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"/>

برای اندروید های 4 به بعد
<Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"/>

 

22- در بعضی موارد با اضافه کردن header های زیر در HttpClient یا UrlConnection تون، مشکل FileNotFoundException رفع خواهد شد:

"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*"
"User-Agent", "Mozilla/5.0 ( compatible ) "

 

23- آیا می دونید در try/finally بلوک finally همیشه اجرا میشه، بجز زمانی که System.exit صدا زده بشه یا VM کرش کنه؟

 

24- در بعضی موارد با استفاده از getText().clear() بجای setText("")، خطای X on inactive InputConnection برطرف خواهد شد.

 

25- همچنین در بعضی موارد، با بستن Keyboard برنامه قبل از بستن شدن Fragment/Activity، خطای showStatusIcon on inactive InputConnection برطرف خواهد شد:

@Override
protected void onPause()
{
    super.onPause();
    View _view = getCurrentFocus();

    if (_view != null)
    {
        final InputMethodManager _imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (_imm != null)
        {
            _imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
        _view.clearFocus();
        _view.setFocusable(false);
    }
}

 

26- در صورتی که از UrlConnection برای POST استفاده می کنید و با خطای ProtocolException: content-length promised x bytes, but received 0 مواجه شدید(در اندروید 4 به بعد)، بدونید که نباید Content-Length رو خودتون تنظیم کنید و باید به عهده خود UrlConnection بذارید تا تنظیمش کنه... پس اون خط رو حذف کنید.

 

27- برای اینکه کیبورد نرم افزاری، در حالت landscape تمام صفحه رو پوشش نده، باید:

- خاصیت android:windowSoftInputMode="adjustResize" رو به تگ Activity فایل AndroidManifiest.xml اضافه کنید.

- یا خاصیت android:imeOptions="flagNoExtractUi" رو به تگ EditText فایل layout اضافه کنید.

 

28- یک تابع پیشنهادی بهبود یافته برای استفاده از ClipboardManager، سازگار با تمام نسخه های اندروید:

public static final void copyToClipboard(final Context context, final EditText editText)
{
    final ClipboardManager _clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);

    if (_clipboardManager != null)
    {
        if (Build.VERSION.SDK_INT >= 3) // Honeycomb
        {
            final ClipData _clipData = ClipData.newPlainText(" ", editText.getText().toString());
            _clipboardManager.setPrimaryClip(_clipData);
        }
        else
        {
            _clipboardManager.setText(editText.getText().toString());
        }
    }
}

 

29- در اندروید 2 به قبل می تونید با استفاده از کتابخانه appcompat-v7، johannilsson android-actionbar یا ActionBarSherlock به برنامه تون ActionBar اضافه کنید.

 

30- نکاتی درباره متد toString() و valueOf():

- متد valueOf در پشت پرده متده toString رو صدا می زنه.

- از نظر سرعت، متد toString کمی سریعتر از متد valueOf هستش.

- valueOf رو میشه گفت flexible تره و بازه دیتایی بیشتری رو قبول می کنه.

- اگر داده ورودی به این متد ها NULL باشه، متد toString اثتثنای NullPointerException پرتاب میکنه، در صورتی که متد valueOf رشته "null" رو برمیگردونه(null-safe هستش).

- valueOf یک متد static هستش، درصورتی که toString یک متد object.

نظرات (۱)

۰۶ آبان ۹۵ ، ۱۳:۱۳ فرهاد حسن‌پور
ممنون بهرمند شدیم.
کاربران بیان میتوانند بدون نیاز به تأیید، نظرات خود را ارسال کنند.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">