مشخصات مقاله
-
1737
-
0.0
-
3507
-
0
-
0
ابزار تحلیل و سنجش کارایی اپلیکیشن های اندرویدی
مرور کلی
کارایی اپلیکیشن های اندرویدی در اجرای تمامی عملیات با سرعت هر چه تمام تر از اهمیت ویژه ای برخوردار است. مبحث جاری کلیه ی ابزار موجود اندروید در ره گیری و بهینه سازی اپلیکیشن را عنوان می کند.
StrictMode
توسعه دهنده می بایست تا حد امکان از اجرای عملیات طولانی، سنگین و هزینه بر در thread اصلی (UI thread) خودداری کند. از جمله ی این عملیات می توان به دسترسی به فایل و اینترنت اشاره کرد.
برای دستیابی به این هدف می توان از StrictMode بهره گرفت. این حالت عملیاتی (StrictMode) از ورژن 9 توابع کتابخانه ای اندروید (API ورژن 9) برای اولین بار در چارچوب نرم افزاری اندروید معرفی شده و به توسعه دهنده این امکان را می دهد تا برای اپلیکیشن سیاست ها و قوانین خاصی حاکم بر مدیریت thread ها به نام thread policy تعریف کند.
به واسطه ی StrictMode توسعه دهده می تواند به سیستم اندروید دستور بدهد تا چنانچه اپلیکیشن عملیات سنگین و طولانی همچون دریافت ورودی/خروجی (I/O) را در thread اصلی به اجرا گذاشت، بلافاصله اپلیکیشن را متوقف سازد.
کد زیر نحوه ی استفاده از StrictMode را به نمایش می گذارد. به مجرد اینکه کامپوننت activity این تنظیمات و قوانین تنظیم شده را نقض کرد، سیستم اندروید آن را به طور ناگهانی متوقف می سازد.
package de.vogella.android.strictmode;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
public class TestStrictMode extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Activate StrictMode
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectAll()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
// alternatively .detectAll() for all detectable problems
.penaltyLog()
.penaltyDeath()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
// alternatively .detectAll() for all detectable problems
.penaltyLog()
.penaltyDeath()
.build());
// Test code
setContentView(R.layout.main);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String eol = System.getProperty("line.separator");
try {
BufferedWriter writer =
new BufferedWriter(
new OutputStreamWriter(
openFileOutput("myfile",
MODE_WORLD_WRITEABLE)));
writer.write("This is a test1." + eol);
writer.write("This is a test2." + eol);
writer.write("This is a test3." + eol);
writer.write("This is a test4." + eol);
writer.write("This is a test5." + eol);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
StrictMode تنها در مرحله ی توسعه ی نرم افزار قابل استفاده می باشد. توصیه می شود از بکار بردن آن در یک اپلیکیشن توزیع و نصب شده که به صورت نهایی اجرا می شود، خودداری گردد.
بخش Developer Settings در Setting اپلیکیشن گوشی اندروید به شما این امکان را می دهد تا تنظیماتی را تعیین کنید که تحلیل و سنجش کارایی اپلیکیشن را آسان می سازد. به عنوان مثال شما می توانید اعلان کنید که محل برخورد انگشت با نمایشگر هایلایت شود.
برای مثال چنانچه ویرایش 4.2 اندروید بر روی دستگاه شما نصب است، برای دسترسی به بخش تنظیمات مربوط به توسعه دهنده، می بایست به بخش About در Settings مراجعه نموده و بر روی المان Build number هفت بار کلیک نمایید.
در صورتی که گوشی شما این گزینه ی تنظیم را نداشت، می توانید از برنامه ی شبیه ساز (emulator) استفاده نمایید.
در برخی موارد لازم است اپلیکیشن را مجددا راه اندازی کرده تا تنظیمات مورد نظر فعال شده و به درستی عمل کند.
مقدمه
Traceview عبارت است از یک graphical viewer که به شما امکان می دهد تا گزارشاتی (log ها) که اپلیکیشن اندروید ضبط می کند را مشاهده نمایید. به واسطه ی TraceView شما می توانید کارایی اپلیکیشن را سنجیده و مشکلاتی که کارایی اپلیکیشن را پایین آورده و کیفیت تجربه ی کاربری را پایین می آورد، شناسایی و برطرف نمایید.
TraceView به عنوان یک ابزار مستقل در فولدر tools از پوشه ی نصب ابزار توسعه و ساخت اپلیکیشن های اندرویدی / Android SDK installation جایگذاری شده و قابل دسترسی می باشد. توسعه دهنده می تواند با نصب ADT (مجموعه ابزار توسعه ی نرم افزار اندرویدی) آن را در محیط برنامه نویسی Eclipse جاسازی کند.
استفاده از ابزار TraceView در محیط کاری Android Studio
محیط برنامه نویسی به شما امکان می دهد تا از طریق ابزار Android Device Monitor روند اجرای اپلیکیشن را رصد و مشاهده (trace) نمایید. برای این منظور کافی است مسیر رو به روی را طی نمایید: Tools ▸ Android ▸ Android Device Monitor.
جهت فعال سازی قابلیت رد گیری روند اجرای اپلیکیشن، ابتدا فرایند اپلیکیشن خود را در کادر Devices انتخاب نموده و سپس دکمه ی Start Method Profiling را مطابق تصویر زیر کلیک کنید.
اپلیکیشن را اجرا نموده و مجددا دکمه ای که جهت فعال سازی ردگیری جریان اجرای اپلیکیشن (method profiling) کلیک کردید، کلیک نمایید. در پی این اقدام، یک ویرایشگر جدید باز شده، که نتایج ردگیری و ضبط شده از روند اجرای اپلیکیشن را به نمایش می گذارد.
می توانید تصویر را بزرگنمایی کرده و جزئیات را دقیق تر مشاهده نمایید. برای کوچک نمایی، کافی است بر روی خط نمایشگر زمان دوبار کلیک کنید.
راه اندازی و فراخوانی ابزار TraceView از طریق خط دستور (command line)
برای اینکه پروسه ی رصد اجرای کد برنامه (trace) آغاز شود، کافی است تکه کد زیر را بین دو دستور زیر درج نمایید.
android.os.Debug.startMethodTracing("yourstring");
// ... your code is here
android.os.Debug.stopMethodTracing();
پارامتر "yourstring" به سیستم اندروید اعلان می کند که بایستی داده ها را تحت آدرس "/sdcard/yourstring.trace" ذخیره نماید. جهت جایگذاری داده ها در حافظه ی خارجی (sdcard)، اپلیکیشن شما می بایست مجوز WRITE_EXTERNAL_STORAGE را در لایه ی XML تعریف کرده باشد. پس از اجرای اپلیکیشن، می توانید نتایج را با اجرای دستور زیر در پنجره ی فرمان adb (command line tool)، در مسیر دلخواه کپی کنید.
adb pull /sdcard/yourstring.trace traceview yourstring
با فراخوانی این دستور در پنجره ی فرمان adb، ابزار Traceview فعال شده و به شما اجازه می دهد تا داده های مربوط به کارایی اپلیکیشن خود را به صورت دیداری (visual) و قالب اطلاعات قابل مشاهده در نمایشگر بررسی و دنبال نمایید. در کادر DDMS یک دکمه ی trace و ردگیری جریان اپلیکیشن وجود دارد. با استفاده از این دکمه، جریان اجرای اپلیکیشن در حین اجرا و پیشرفت، رصد شده و لزومی به تنظیم مجوز خاصی در لایه ی XML نیست.
تمرین: استفاده ی کاربردی از Traceviewاستفاده از ابزار Traceview در پروژه
یک اپلیکیشن اندرویدی جدید با نام پکیج (top level package) com.vogella.android.traceview ایجاد نمایید.
کلید زیر را به فایل values/strings.xml اضافه نمایید.
Traceview Example Settings Hello world! Random number: %1$s
یک فایل layout با نام rowlayout.xml و محتوای زیر ایجاد نمایید.
یک کلاس adapter برای آبجکت ListView اپلیکیشن خود به صورت زیر پیاده سازی نمایید.
package com.vogella.android.traceview; import java.util.Collections; import java.util.List; import android.content.Context; import android.content.res.Resources; import android.os.Debug; import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; public class MyArrayAdapter extends ArrayAdapter{ private List values; private Context context; public MyArrayAdapter(Context context, List values) { super(context, R.layout.rowlayout); this.context = context; this.values = values; } @Override public View getView(int position, View convertView, ViewGroup parent) { Debug.startMethodTracing("getViewOfTrace"); // Ensure sorted values Collections.sort(values); LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.rowlayout, parent, false); Resources res = context.getResources(); String text = String.format(res.getString(R.string.number_template), values.get(position)); CharSequence styledText = Html.fromHtml(text); TextView textView = (TextView) view.findViewById(R.id.textView3); textView.setText(styledText); Debug.stopMethodTracing(); return view; } }
حال یک آبجکت ListView در کلاس activity (جهت ساخت یک لیست ساده) خود که 1000 رشته با مقدار تصادفی را در صفحه به نمایش می گذارد، پیاده سازی کنید.
package com.vogella.android.traceview;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.os.Bundle;
public class MainActivity extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List list = createValues();
MyArrayAdapter adapter = new MyArrayAdapter(this, list);
setListAdapter(adapter);
}
private static List createValues() {
SecureRandom random = new SecureRandom();
List list = new ArrayList();
for (int i = 0; i < 1000; i++) {
String string = new BigInteger(130, random).toString(32);
list.add(string);
}
return list;
}
}
مجوز لازم برای ذخیره و درج اطلاعات در حافظه ی خارجی دستگاه خود را در لایه ی XML اپلیکیشن اعلان نمایید.
رصد و سنجش کارایی اپلیکیشن (Trace)
اپلیکیشن خود را اجرا کنید . سپس از طریق adb به دستگاه مربوطه وصل شده و اطلاعات مربوط به رصد کارایی اپلیکیشن را در حافظه جایگذاری نمایید. حال خروجی مربوط به کارایی اپلیکیشن را تجزیه و تحلیل کنید.
برطرف کردن کاستی های مربوط به کارایی اپلیکیشن
اکنون زمان آن فرا رسیده تا کارایی اپلیکیشن را بر اساس اطلاعات و خروجی Traceview افزایش داده و کاستی های آن را در جهت بهبود تجربه ی کاربری برطرف نمایید.
- مقدار attribute ای که ظاهر متن را در متد getView() تعیین می کند (مقدار متن را بر روی bold یا برجسته تنظیم می کند)، با دستور android:textStyle="bold متناظر در لایه ی XML، داخل فایل LAYOUT جایگزین نمایید تا بدین وسیله از فراخوانی متد Html.fromHtml() جلوگیری شود.
- مرتب سازی را به مکان دیگری انتقال دهید.
- چنانچه مقدار convertView برابر null نبود، از آن بار دیگر در کلاس Adapter استفاده نمایید.
- با پیاده سازی الگو توسعه ی HolderPattern در آبجکت ListView، از فراخوانده شدن متد findViewById() جلوگیری نمایید.
layout به طور بهینه طراحی نشده است. مثال فوق را در تمرین HierarchyView مجددا بکار خواهیم برد.
Hierarchy Viewer (ابزار نمایش درختی view ها)
Hierarchy View به شما این امکان را می دهد تا نمودار درختی و سلسله مراتبی View اپلیکیشن اندروید خود را به صورت دیداری در محیط کاری اندروید ترسیم کرده و سپس لایه های غیرضروری و اضافی را در نمودار درختی مزبور شناسایی نمایید.
برای دسترسی به Hierarchy View، کافی است مسیر رو به رو را طی نمایید: Window ▸ Open Perspective ▸ Other… ▸ Hierarchy View.
در view یا کادر Widows می توانید فرایندی که می خواهید view hierarchy برای آن مورد تحلیل قرار گیرد را انتخاب نمایید.
layout ای که در حال حاضر فعال می باشد، مورد تحلیل قرار گرفته و به نمایش گذاشته می شود.
کادری که Tree View نام دارد، در هر یک از view ها سه دایره ی کوچک رنگی به نمایش می گذارد. اولین دایره، مدت زمانی که برای محاسبه ی اندازه ی view لازم است را بیان می کند. دومین دایره بیانگر زمان لازم برای ایجاد layout و طرح کلی می باشد و سومین دایره مدت زمان لازم برای ترسیم view را نشان می دهد. کارهای هزینه بر و طولانی با رنگ زرد یا قرمز برای برنامه نویس نمایش داده می شود.
تمرین: استفاده ی کاربردی از ابزار Hierarchy Viewerدر تمرین جاری، همچنان از مثال قبلی که در تمرین Traceview بکار برده شد، استفاده خواهیم کرد. Hierarchy View را باز کرده و لایه ی view را دقیق مورد بررسی قرار دهید.
گرچه هیچ یک از لایه های layout، با توجه به دایره ی رنگی داخل view ها، از نظر منابع مورد استفاده و زمان اجرا هزینه بر و طولانی نیستند، با این وجود لایه ها و view های غیرضروری در آن به چشم می خورند. حال لایه های غیرضروری را حذف نمایید.
بهینه سازی Layout
اکنون زمان آن فرا رسیده که فایل layout تنظیم کننده ظاهر و طرح کلی اپلیکیشن خود را بهینه نمایید. تصویر زیر با مثال نمایش می دهد چگونه با استفاده از Framelayout و دو المان رابط کاربری ImageView و TextView نتیجه ی ارائه شده را تولید نمایید. همان طور که در تصویر حاضر مشاهده می کنید، کامپوننت رابط کاربری TextView در layout جایگذاری شده و محتوای متنی آن به دو روش متفاوت سبک یا style دهی شده اند.
یک پروژه ی جدید به نام com.vogella.android.textview.spannablestring ایجاد نمایید.
حال دو attribute سبک دهی (styles) جدید به محتوای فایل styles.xml اضافه نمایید.
یک فایل layout با محتوای زیر ایجاد نمایید.
متن موجود در المان TextView خود را، همان طور که در کد زیر نمایش داده شده، با دو نمونه ی مجزا از TextAppearanceSpan سبک دهی و تنظیم (style) نمایید.
package com.vogella.android.textview.spannablestring;
import android.app.Activity;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.TextAppearanceSpan;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.input);
String header = "This is the header";
String description = "This is the description";
Spannable styledText = new SpannableString(header + "\n" + description);
TextAppearanceSpan span1 = new TextAppearanceSpan(this,
R.style.textHeader);
TextAppearanceSpan span2 = new TextAppearanceSpan(this,
R.style.textbody);
styledText.setSpan(span1, 0, header.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
styledText.setSpan(span2, header.length() + 1, header.length() + 1
+ description.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(styledText);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
در نهایت مشاهده خواهید کرد که layout جدید بسیار سریع تر از layout قبلی که مبتنی بر RelativeLayout می باشد، عمل می کند. لازم به توضیح است که در layout جاری از styling HTML خودداری شده چرا که استفاده از مفسر با تبدلیگر HTML parser بسیار هزینه بر و سنگین می باشد.
تهیه ی روگرفت از حافظه (Memory Dumps)
در صورت تمایل می توانید یک روگرفت یا تصویر لحظه ای از حافظه تهیه کرده و سپس آن را به واسطه ی ابزار Memory Analyzer محیط کاری Eclipse بررسی و تحلیل نمایید.
ابزار Systrace
Systrace به شما این امکان را می دهد تا کارایی اپلیکیشن را خود به طور مسقیم در سطح هسته ی سیستم (kernel level) بررسی نمایید. جهت فعال سازی این ابزار، پس از انتخاب Developer options، المان Enable traces را کلیک نمایید. در کادر محاوره ی (dialog) بعدی، می توانید به طور صریح مشخص نمایید از کدام event ها، Graphics and View به عنوان مثال، بایستی گزارش تحلیلی و جزئی تهیه شود (profile شود).
به منظور استفاده از ابزار systrace، یک پنجره ی فرمان (terminal) باز کرده، سپس systrace.py را از پوشه ی اصلی (directory) android_sdk_installdir/tools/systrace اجرا نمایید. ممکن است لازم باشد آن را بر روی یک فایل اجرایی (executable) تنظیم نمایید (در لینوکس chmod a+x systrace.py).
در صورت تمایل می توانید ابزار مزبور را از طریق DDMS مسقیما از محیط کاری Eclipse اجرا نمایید.
ابزار Systrace رخدادها را به مدت پنج ثانیه ضبط (capture) می کند. در نتیجه، ابزار نام برده یک فایل HTML ایجاد کرده و به شما این امکان را می دهد تا مشکلات احتمالی را تجزیه و تحلیل نمایید.
شبیه سازی چگالی یا تراکم پیکسلی (pixel density) از طریق خط دستور
شما می توانید با استفاده از خط دستور (command line)، چگالی پیکسلی و وضوح تصویر دستگاه های مختلف اندروید را شبیه سازی کنید. این امر به شما اجازه می دهد تا از یک دستگاه استفاده کرده و به وسیله ی آن، چگالی پیکسلی و وضوح تصویر دیگر دستگاه های اندروید را شبیه سازی نمایید.
// Set the display size adb shell am display-size 600x800 // Set the display density adb shell am display-density 80
قالب های آماده یا الگوهای پیاده سازی پروژه ی اندروید (Android template)
شما می توانید قالب های آماده دلخواه خود را برای ویزاد ساخت پروژه ی اندروید (Android project creation wizard) تعریف نمایید. جهت دستیابی به اطلاعات بیشتر در این زمینه می توانید به لینک های زیر مراجعه نمایید: https://plus.google.com/113735310430199015092/posts/XTKTamk4As8.
قالب و الگوهای بیشتر کدنویسی (code template) تحت آدرس https://github.com/jgilfelt/android-adt-templates قابل دسترسی می باشد.
گزارش گیری و ثبت اطلاعات مربوط به کارایی موتور گرافیکی (ابزار Profile GPU rendering)
در بخش Developer Options، داخل Settings یا در دستگاه واقعی اندروید خود، این امکان برای شما وجود دارد که ابزار Profile GPU rendering را فعال نموده و مدت زمان مورد نیاز برای ترسیم 128 فریم توسط سیستم را رصد و ثبت نمایید.
پس از فعال سازی این امکان و راه اندازی مجدد اپلیکیشن، می توانید با فراخوانی دستور زیر در پنجره ی فرمان، اطلاعات مربوطه را واکشی نمایید.
adb shell dumpsys gfxinfo your_package
برای مثال جهت سنجش frame rate (سرعت پخش فریم ها) اپلیکیشن با پیمایش به سمت پایین در یک لیست. در بیشتر موارد، لازم است با اپلیکیشن خود تعامل کنید تا مجبور شود خود را مجددا ترسیم کند.
در گزارش نهایی که در اختیار شما قرار می گیرد، بخشی به نام Profile data in ms را پیدا کنید.
تحلیل و بررسی وضعیت Overdraw (ترسیم یک آیتم بر روی آیتم دیگر)
Overdraw زمانی رخ می دهد که دو آیتم همپوشانی داشته باشند، بدین معنی یک آیتم بر روی آیتم دیگری رسم شود. به طور مثال، می توان به زمانی اشاره کرد که پس زمینه ی کامپوننت activity، یک Window باشد. حال اگر المان TextView به اپلیکیشن اضافه شود، این المان طبیعتا بر روی Window ترسیم شده و قرار می گیرد.
بنابراین وضعیت overdraw یک امر طبیعی بوده و رخداد آن مورد انتظار می باشد. با این حال توصیه می شود جهت بالا بردن کارایی اپلیکیشن و تجربه ی کاربری، از ترسیم آبجکت های متعدد بر روی هم و رخداد overdraw به صورت بیش از حد خودداری شود.
دلیل اصلی رخداد overdraw بی رویه می تواند view hierarchies و نمودار درختی بسیار پیچیده ی view ها باشد. به طور کلی وضعیت 2x overdraw (زمانی که یک پیکسل سه بار ترسیم می شود) یک امر طبیعی است اما بیشتر از آن می بایست اجتناب شود چرا که افت کارایی را به دنبال دارد.
می توانید از طریق Development Settings و فعال گردن گزینه ی Show GPU overdraw، وضعیت رخداده ی overdraw و view های ترسیم شده بر روی هم را به صورت دیداری در نمایشگر داشته باشید. این تنظیم بر اساس overdraw ها، رنگ به صفحه نمایش تخصیص می دهد. جدول زیر مجموعه رنگ بکار رفته را همراه با معنی هر یک شرح می دهد.
پس از دریافت نسخه ی دیداری و بررسی بخش هایی که مشکل زا بودند، می توانید نمودار درختی View را با ابزار Hierarchy Viewer تحلیل نمایید.
ابزار رایگان و متن باز کارا برای تحلیل و بهینه سازی کارایی اپلیکیشن
استفاده از Leak Canary برای یافت و برطرف نمودن هدر رفت حافظه (memory leak)
Leak Canary یک ابزار متن باز است که می توان با اپلیکیشن اندروید ادغام نموده و به کمک آن هدر رفت حافظه را به صورت خودکار شناسایی کرد. استفاده از ابزار نام برده بسیار آسان است و شما می توانید آن را به عنوان کتابخانه (dependency) به فایل Gradle build اضافه نموده و سپس کتابخانه ی مزبور را در کلاس application خود مقداردهی اولیه (initialize) نمایید. با این کار یک lifecycle listener و گوش فراخوان به چرخه ی حیات activity ها اضافه شده و دقیقا بررسی می کند آیا متد destroy آن ها در زمان مناسب فراخوانی می شود یا خیر.
لازم به توضیح است که Canary leak به علت open source بودن به صورت مداوم ویرایش و بروز رسانی می شود. جهت اطلاع از نحوه ی بکارگیری این ابزار به آدرس https://github.com/square/leakcanary، صفحه ی Leak Canarys Github مراجعه نمایید.
استفاده از AndroidDevMetrics جهت مشاهده ی اطلاعات مربوط به کارایی اپلیکیشن
ابزار AndroidDevMetrics به توسعه دهنده این امکان را می دهد تا سرعت اجرای عملیات معمول همچون مقداردهی اولیه ی آبجکت یا فراخوانی توابع مدیریت چرخه ی حیات (lifecycle) Activity (از جمله onCreate()،onStart() و onResume()) را تحلیل نماید.
همان طور که درباره ی ابزار قبلی گفته شد، AndroidDevMetrics یک پروژه ی متن باز (Open Source) است. بدین معنی که ممکن است به صورت مداوم بروز رسانی شده و مورد ویرایش قرار گیرد. برای اطلاع از نحوه ی استفاده از این ابزار متن باز می توانید به آدرس https://github.com/frogermcs/androiddevmetrics - صفحه ی AndroidDevMetrics مراجعه نمایید.