یادداشت های یک توسعه دهنده از جهان برنامه نویسی

۴ مطلب با کلمه‌ی کلیدی «programming» ثبت شده است

دیباگ مستقیم اپ روی گوشی

حتما برای دولاپر های عزیز اندروید پیش اومده که بعد از آماده سازی اولیه اپ و نصب روی گوشی ، در حالی که به نظر میاد همه چیز داره خوب کار میکنه اپ کرش می کنه و یه سوال بسیار بزرگ عین شاخ از سرشون بیرون میزنه  ! اگر مثل من دسترسی به محیط دیباگ android studio به سرعت در اختیارتون نیست و یا نمیدونید کجا خطا اتفاق افتاده تا سریع برید همون خط رو دیباگ دوباره کنید و میخواید که خطا روی خود گوشی بهتون نمایش داده بشه ، این روش کارایی خوبی خواهد داشت .

Android Global Exception Handler

اینکار به سادگی با java.lang.Thread.UncaughtExceptionHandler قابل انجامه ولی باید یکی از دو روش زیر رو انتخاب کنید :

1.خطایابی در سطح Application که در این صورت نمی توانید dialog باز کنید و یا اکتیویتی جدیدی اجرا کنید با این حال هر نوع خطایابی قابل اجرا خواهد شد 

2.خطایابی در سطح Activity که به راحتی میتوان dialog یا اکتیویتی دیگری باز کرد ولی باید در یک کلاس ارث بری شده توسط اکتیویتی ها نوشته شود ( مثلا BaseActivity )

خطایابی در سطح Application

در این روش log ایرور بصورت فایل روی دستگاه ذخیره خواهد شد تا در اجرای دوباره اپ بتوان از آن استفاده کرده و متن خطا را نمایش داد 


public class LoggingExceptionHandler implements Thread.UncaughtExceptionHandler {
    private final static String TAG = LoggingExceptionHandler.class.getSimpleName();
    private final static String ERROR_FILE = MyAuthException.class.getSimpleName() + ".error";
    private final Context context;
    private final Thread.UncaughtExceptionHandler rootHandler;
    public LoggingExceptionHandler(Context context) {
        this.context = context;
        // we should store the current exception handler -- to invoke it for all not handled exceptions ...
        rootHandler = Thread.getDefaultUncaughtExceptionHandler();
        // we replace the exception handler now with us -- we will properly dispatch the exceptions ...
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    @Override
    public void uncaughtException(final Thread thread, final Throwable ex) {
        try {
            Log.d(TAG, "called for " + ex.getClass());
            // assume we would write each error in one file ...
            File f = new File(context.getFilesDir(), ERROR_FILE);
            // log this exception ...
            FileUtils.writeStringToFile(f, ex.getClass().getSimpleName() + " " + System.currentTimeMillis() + "\n", true);
        } catch (Exception e) {
            Log.e(TAG, "Exception Logger failed!", e);
        }
    public static final List<String> readExceptions(Context context) {
        List<String> exceptions = new ArrayList<>();
        File f = new File(context.getFilesDir(), ERROR_FILE);
        if (f.exists()) {
            try {
                exceptions = FileUtils.readLines(f);
            } catch (IOException e) {
                Log.e(TAG, "readExceptions failed!", e);
            }
        }
        return exceptions;
    }
}

حالا باید ان را به سطح Application ضمیمه کنیم


public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        new LoggingExceptionHandler(this);
    }
}

یادتان نرود که در فایل AndroidManifest  نیز تغییرات زیر را انجام دهید 

<application
    android:name=".MyApp"

خطایابی در سطح Activity

در این روش با استفاده از ApplicationContext می توان log ایرور را بصورت مستقیم نشان داد و یا حتی اکتویتی جدیدی را اجرا کرد 

public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {

    public static final String EXTRA_MY_EXCEPTION_HANDLER = "EXTRA_MY_EXCEPTION_HANDLER";
    private final Activity context;
    private final Thread.UncaughtExceptionHandler rootHandler;

    public MyExceptionHandler(Activity context) {
        this.context = context;
        // we should store the current exception handler -- to invoke it for all not handled exceptions ...
        rootHandler = Thread.getDefaultUncaughtExceptionHandler();
        // we replace the exception handler now with us -- we will properly dispatch the exceptions ...
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(final Thread thread, final Throwable ex) {
        if (ex instanceof MyAuthException) {
            // note we can't just open in Android an dialog etc. we have to use Intents here
            // http://stackoverflow.com/questions/13416879/show-a-dialog-in-thread-setdefaultuncaughtexceptionhandler

            Intent registerActivity = new Intent(context, AuthActivity.class);
            registerActivity.putExtra(EXTRA_MY_EXCEPTION_HANDLER, MyExceptionHandler.class.getName());
            registerActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            registerActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);

            context.startActivity(registerActivity);
            // make sure we die, otherwise the app will hang ...
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
        } else {
            rootHandler.uncaughtException(thread, ex);
        }
    }
}

برای ضمیمه کردن این Handler باید یک کلاس ایجاد کرد تا اکتیویتی های دیگر از آن ارث بری کنند 


public abstract class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new MyExceptionHandler(BaseActivity.this);
    }
}
خودم از این روش در پروژه هام استفاده میکنم و معمولا وقتی ایرور جدید غیر قابل پیش بینی اتفاق می افته خیلی بدردم خورده ... البته چون از روش دوم استفاده میکنم بعضی از ایرور های که قبل از activity اتفاق می افتن رو نمیشه catch کرد که زیاد چنین اتفاقی نمی افته . من برای نمایش متن ایرور از اکتویتی جدید و یک TextView استفاده میکنم . البته نمی دونم بدلیل محدودیت String و یا TextView کل متن ایرور نمایش داده نمیشه که زیاد فرقی نمیکنه و معمولا از همون خطوط اول مشخص میشه خطا برای چیه 
۰ نظر موافقین ۰ مخالفین ۰
مرتضی درزی

Learnable Programming - برنامه نویسی قابل یادگیری - قسمت اول

با ترجمه و اقتباس از مقاله آقای برت ویکتور - Learnable Programming

موضوع اصلی این سری از مطالب در خصوص نحوه یادگیری یک زبان برنامه نویسی و درک کد های برنامه است . اینکه با چه روشی میتوان برنامه نویسی را به دیگران آموزش داد و محیط و زبان برنامه نویسی باید دارای چه خصوصیاتی باشد . ایده اصلی  Learnable programmingاز آقای برت ویکتور می باشد که این مطلب سعی میکند همراه با ترجمه ، تفکرات ذهنی نویسنده را نیز بیان کند .

موضوعات مطرح شده در این سری از مطالب ، در محیط آنلاین آموزشی آکادمی خان و براساس زبان برنامه نویسی جاوا اسکریپت ( js ) و Processing نوشته شده که دارای ویژگی مثل live coding می باشد که به محض نوشته شدن کد ، خروجی آن قابل مشاهده میباشد .

برنامه نویسی

برنامه نویسی یعنی فکر کردن ، نه فقط مهارت نوشتن کد . ما در برنامه نویسی یه پروسه فکری را ایجاد کرده و به آن می پردازیم و سعی میکنیم مشکلات را در این پروسه حل کنیم . به عنوان مثال ، صرف یادگیری حلقه for یادگیری برنامه نویسی نیست و مثل این می ماند که بخواهیم با یادگیری نحوه استفاده از مداد ، طراحی را یاد بگیریم. در برنامه نویسی سعی می کنیم با بررسی مساله یک حالت مفهومی را ایجاد کنیم تا پاسخگویی تمام ورودی ها و خروجی های کاربر قرار بگیرد . 

دیدن نتایج

همه ما آنچه را بتوانیم ببینیم بهتر درک میکنیم . در برنامه نویسی نیز یادگیرنده باید بتواند نتایج برنامه ای را که مینویسد ببیند . اینجا مقصود از نتایج خروجی برنامه نیست ، بلکه امکانی است برای یادگیرنده تا بتواند یک خروجی از هر خط کدی که مینویسد ببیند و درک کند این قطعه از کد چه کاری انجام خواهد داد و الزاما نیاز نیست منتظر خروجی کل برنامه در پایان کار باشد. هدف کلی یک سیستم برنامه نویسی :

تشویق و ترغیب یادگیرنده در استفاده از روش های قدرتمند فکر کردن

ایجاد امکان دیدن و فهمیدن جزئیات برنامه به یک یادگیرنده

آلن پرلیز ( Alan Perlis ) میگوید : " برای اینکه یک برنامه را بفهمید باید خود را جای انسان و ماشین قرار دهید و مثل انها فکر کنید "

این یک اشتباه بزرگ است . دقیقا چیزی که برنامه نویسی را سخت و غیر قابل اطمینان میکند . یک انسان هرگز نمیتواند مثل یک ماشین فکر کنید ، نحوه فکر کردن یک انسان بسیار با ماشین متفاوت است و ما برای فکر کردن نیاز به تجسم داریم در حالی که ماشین از روش های موجود استفاده میکند . حال سوال این است که پس چطور باید برنامه نویسی را به دیگران آموزش دهیم . ما سیستم برنامه نویسی را طوری تغییر میدهیم تا قابل فهمیدن توسط انسان باشد .


سیستم برنامه نویسی 

هر سیستم برنامه نویسی دو بخش دارد . یک بخش آن محیط برنامه نویسی است که روی کامپیوتر نصب میشود و محیطی را برای کار کردن برنامه نویس ایجاد میکند و یک بخش نیز زبان برنامه نویسی است که روی مغز برنامه نویس نصب میشود . و با استفاده از ان با کامپیوتر ارتباط برقرار می کند . باید هر دو بخش سیستم برنامه نویسی براساس اصولی طراحی شود که قابلیت یادگیری داشته باشد . یعنی همان شعار Learnable-Programming که سیستمی را برای برنامه نویسی ترسیم خواهد کرد که ، یادگیرنده در جایگاه خود به عنوان یک انسان و از دیدگاه خود برنامه را تحلیل کرده و بسازد .
یک محیط برنامه نویسی قابل یادگیری باید به یادگیرنده اجاز دهد :
  1. کلمات را بخواند ( read the vocabulary ) - کلمات چه معنایی میدهند ؟
  2. جریان داده را دنبال کند ( follow the flow ) - چه اتفاقی چه موقع می افتد ؟
  3. وضعیت ها را مشاهده کند ( see the state ) - کامپیوتر چطور فکر میکند ؟
  4. با واکنش نشان داد بسازد ( create by reacting ) - از نقطه ای شروع کرده و بسازد 
  5. بصورت مفهومی بسازد ( create by abstracting ) - ابتدا پیاده سازی کرده و سپس تعمیم دهد
یک زبان برنامه نویسی نیز باید شامل موارد زیر باشد :
  1. هویت و استعاره ( identity and metaphor ) - چطور باید جهان کامپیوتر را با جهان خودمان ارتباط دهیم ؟
  2. تجزیه ( decomposition ) - چطور باید ایده های خود را به تکه های قابل فهم تجزیه کنم ؟
  3. ترکیب دوباره ( recomposition  ) - چطور باید تکه های ذهنی را بهم بچسبانم ؟
  4. قابلیت خوانایی ( readability ) - این کلمات چه معنایی میدهند ؟
سعی خواهم کرد در سری های بعدی مطالب هر بخش از ویژگی های محیط و زبان برنامه نویسی را که در بالا لیست شده بصورت مجزا توضیح دهم 

 

۱ نظر موافقین ۰ مخالفین ۰
مرتضی درزی

تصاویر برداری ( Vector Drawable ) در اندروید

تصاویر برداری یا همان Vector Drawable نوعی از تصاویر هستند که با استفاده از محاسبات ریاضی و برداری ساخته میشوند و نسبت به تصاویر PNG  , JPG  کاربرد های بیشتری در طراحی رابط کاربری موبایل و وب دارند . از جمله مزیت بسیار خوب این تصاویر امکان تغییر سایز تصاویر در رزولوشن های متفاوت بدون از دست دادن جزئیات می باشد . 

 

تفاوت در چیست ؟

تصاویر برداری با محاسبات ریاضی ساخته می شوند ، مبنای این محاسبات نیز اندازه نمایی ( View ) است که در آن قرار گرفته اند .این یعنی اینکه اگر یک فایل برداری را در رزولوشن 320*240 قرار دهید ، تمام محاسبات از روی همین اندازه انجام گرفته و بردار ها بر اساس آن ساخته می شود و با قرار دادن همان فایل برداری در رزولوشن 1288*768 محاسبات دوباره بر اساس اندازه جدید انجام میگیرد . اما در تصاویر پیکسلی ، این پیکسل های تصاویر هستند که در هر رزولوشن جایگذاری میشوند و با تغییر اندازه تصاویر ، پیکسل ها تغییری نمی کنند و اطلاعات جدیدی برای افزایش کیفیت تصاویر به آن اضافه نمی شود . عملا تصاویر برداری با تبدیل تصاویر به یکسری بردار ریاضی و به تاخیر انداختن ساخته شدن تصویر تا زمان مشخص شدن اندازه نما در زمان اجرا تصاویر با کیفیت تری را تولید می کنند 

استفاده از تصاویر برداری در اندروید 

برای استفاده از تصاویر پیکسلی در اپلیکیشن ها باید از قبل فایل متفاوتی از یک تصویر برای روزلوشن های متفاوت صفحه نمایش در پوشه res پروژه گنجانده شود تا اندروید در زمان اجرا با توجه به روزلوشن دستگاه اجرا کننده تصویر درست را در صفحه نمایش دهد 

 


ولی پس از معرفی تصاویر برداری در اندروید lollipop و SDK 21 ، توسعه دهندگان می توانند تنها با یک فایل به فرمت xml ، تصاویر با کیفیت را برای روزلوشن های مختلف در اپلیکیشن های خود استفاده کنند . این فایل ها در پوشه drawable قرار میگیرند . 

 

تصاویر برداری را میتوان در android studio 3+  و SDK 23+ و Gradle 3+ به راحتی به کار برد .

تنظیمات مورد نیاز 

ابتدا باید در قسمت تنظیمات Gradle به بخش default config کد زیر را اضافه کنید . با این کار امکان استفاده از support library برای تصاویر برداری امکان پذیر میشود .

defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }

همچینی نیاز است تا کد های زیر نیز به قسمت dependencies اضافه شود تا برای ورژن های پایین تر ، از support library برای نمایش آن استفاده شود 

dependencies {
    implementation 'com.android.support:support-v4:27.1.1'
    implementation 'com.android.support:appcompat-v7:27.1.1'
}

بهتر است بجای کامپوننت های پیش فرض اندروید که قابلیت قرار گیری تصاویر در آن قرار دارد از کامپوننت های support library  بصورت زیر استفاده کنید . در این صورت نمایش تصاویر در ورژن های اندروید 21 به بالا بدون مشکل خواهد بود . 

  android.support.v7.widget.AppCompatButton
  android.support.v7.widget.AppCompatImageButton
  android.support.v7.widget.AppCompatImageView

جهت اختصاص تصاویر به این کامپوپنت های باید از app:srcCompat استفاده شود 

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/img_demo"
        android:layout_width="120dp"
        android:layout_height="120dp"
 app:srcCompat="@drawable/ic_heart" />

در صورت نیاز میتوان بصورت کد نویسی نیز تصاویر برداری را به کامپوننت ها اختصاص داد که نمونه کد آن در زیر آمده است 

// set vector drawable by ID 
val drawable = AppCompatResources.getDrawable(mContext, R.drawable.ic_heart)
img_demo.setImageDrawable(drawable)

در صورت نیاز به استفاده از تصاویر برداری برای اندروید با ورژن های 21 به پایین تر نیز باید علاوه بر تنظیمات و روش های گفته شده بالا ، باید تنظیمات زیر را نیز انجام دهید 

ابتدا برای هریک از فایل های تصاویر خود یک wrapper به شکل زیر با فرمت xml ایجاد میکنید و تصاویر برداری را در آن آدرس دهی میکنید

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_heart"/>
</layer-list>

همچنین در اکتیویتی که این تصاویر را در آن نمایش میدهید نیز در بخش onCreate قطعه کد زیر را قرار دهید . 

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
}

ساخت تصاویر برداری در اندروید استدیو

میتونید در اندروید استودیو فایل های با فرمت svg و psd را به تصاویر برداری تبدیل کنید برای اینکار مثل تصویر به منوی Vector Asset رفته و فایل های مورد نظر را انتخاب کنید 

 

 

منابع جهت مطالعه 

تبدیل فایل های svg به vectordrawable 

http://inloop.github.io/svg2android/

ساخت فایل های svg

https://app.svgator.com

http://app.inker.co

https://vectr.com/

ساخت تصاویر برداری انیمیشن 

https://shapeshifter.design/

ساخت آیکون و تصاویر 

https://romannurik.github.io/AndroidAssetStudio/

کتابخانه برای استفاده از 2000 ایکون متریال بصورت تصاویر برداری 

https://github.com/code-mc/material-icon-lib


۰ نظر موافقین ۰ مخالفین ۰
مرتضی درزی

برنامه نویسی آموزش پذیر ( Learnable Programming)

تو گشت های اخیرم تو نت یه مطلب جالب از سکان آکادمی توجه منو جلب کرد . موضوع درمورد Learnable Programming بود . آقای برت ویکتور یه ایده ای در آکادمی خان پیاده سازی کردند که اومده یه محیط آموزشی برنامه نویسی با ویژگی های خاص مثل اجرای زنده کد ، کد نویسی ویژوال و خیلی چیزهای باحال دیگه ساختن که براساس این ایده که یک برنامه نویس باید نتیجه کارهایی که میکنه رو بصورت ویژوال بتونه ببینه و بررسی کنه کار میکنه . جدای از بحث محیط آموزشی که ساخته شده ، خود ایده Learnable Programming برام یه جذابیت خاصی داره 

سوالی که بعد از چند سال برنامه نویسی ذهنم رو به چالش میکشید این بود که چرا ما نتیجه چیزی که میسازیم رو باید به این سختی ببینیم . مثلا تو اندروید شما کلی کد میزنی و مینویسی تا بالاخره پروژه Build بشه و روی دستگاه فیزیکی یا مجازی اجرا کنی تازه ببینی چی میشه !! ... چرا باید نتیجه کار اینقدر دیر بدست بیاد . خیلی وقت ها برای خود من پیش اومده یه فرضی رو برنامه نویسی میکنم و در ذهنم میچینم و کد هاش رو می نویسم ، وقتی نتیجه کار رو میبینم تازه میفهمم کلا مفهوم کار مشکل داره . در حالی که اگه بتونیم تغییرات رو به صورت زنده ببنیم همونجا میشه خیلی چیزها رو ساخت ..

آقای ویکتور تو سایتشون خیلی از مفاهیم ویژوالی رو برای آموزش یه زبان نشون دادن و میتونید به واقع نتیجه تفاوت برنامه نویسی ویژوال و برنامه نویسی صرفا کد رو ببنید . حتی تو این مطلبشون خیلی زیبا تونستن یک مفهوم ( Abstraction ) رو بصورت پیاده سازی شده در بیارن .. من که به شخصه واقعا مجذوب این سایت و کارهای ایشون شدم ولی ذهنم درگیر یه موضوع بزرگتره ... چرا نتونیم از همین ویژوال و امکاناتش در برنامه نویسی ( خود برنامه نویسی نه آموزش یه زبان برنامه نویسی ) استفاده کنیم . یکی از کارهایی که میشه گفت خواسته یا ناخواسته در همین راستا بوده ویژگی جدید Navigation Architecture Component در کامپوننت اندروید که بصورت کاملا ویژوال امکان navigation بین صفحات مختلف یه اپ رو پیاده سازی و طراحی میکنه ... این همون نتیجه کاریه که باید زودتر ببنیم . 


من حتی میزارم ذهنم از این چیزها هم بگذره و میگم چرا نباید unit test ها هم بصورت ویژوال اجرا بشه ... اینکه شما در یک نما بتونید تغییرات مختلف خروجی رو با توجه به تغییرات ورودی ببینید یه امکان فوق العاده کار راه انداز ... مثل یکی از مواردی که آقای ویکتور در سایتشون نشون دادن  . که در تصویر هم مشخصه . حالا فرض کنید همین خطوط ابی روش های اجرا با توجه به ورودی های مختلف باشه نتایج خروجی های یک متد در یک unit test . فکر میکنم به راحتی بشه نقاط خارج از منطق مورد انتظار رو پیدا کرد و به راحتی یه کار چند ساعته تو ذهن رو به سادگی چند کلیک انجام داد . 

یا حتی بازم بزارید ذهنمون پرواز کنه ، چه خوب میشد بتونیم data flow رو در یه کلاس یا متد دید !! یا نتایج یه تغییر در یک قطعه کد رو به صورت نتیجه یه خروجی نرم افزار دید . این ها همه نشخوار ذهنه و نمی دونم اصلا چی دارم میگم ولی این مطلب خون تازه ای در رگهام جاری کرده و میخوام بیشتر بدونم و بیشتر بفهمم ... شاید در آینده یه مطلب در مورد نتایج مطالعه ام نوشتم . تا اینجا تونستم یه وب سایت ( Processing Foundation ) که بصورت عملی همین ایده رو اجرایی میکنه پیدا کنم که هنوز در حال مطالعه اش هستم . 

شما هم اگه اطلاعاتی دارید که میتونه راهنماییم کنه خوشحال میشم بفرمائید .

 

۰ نظر موافقین ۱ مخالفین ۰
مرتضی درزی