یوشا

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

یوشا

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

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

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

1- بهتره همیشه شماتیک :file رو در کلاس WebView رو مسدود کنید.

کلاس WebView قابلیت نمایش صفحات وب در داخل اکتیویتی رو فراهم میکنه، و از اونجایی که دیگر برنامه ها قادرن Intent URI به WebView ایجاد شده بفرستن، پس این امکان رو هم دارن تا بتونن فایل یا آدرس URI آلوده رو در دستگاه بارگذاری کنن...

راه حل:

String _intentUrl = getIntent().getStringExtra("http://blog.ir");

if (!_intentUrl.startsWith("file:"))
{
   loadUrl = _intentUrl;
}

 

2- از انجایی که همه برنامه ها قادرن محتوای logcat رو read کنن، هرگز اطلاعات حساس رو برای دیباگ Log نکنید، مخصوصاً درخواستها و پاسخهای HTTP رو.

 

3- اگر در حین بازکردن برنامه Eclipse با خطای Java was started but returned exit code 13 مواجه شدید، این یعنی مثلاً Java 64bit نصب کردید، درصورتی که Eclipse تون 32bit هستش. یا Java 32bit نصب کردید، درصورتی که Eclipse تون 64bit هستش.

بنابراین باید معماری هردو یکی باشه... مثلاًً هردو 32bit یا هردو 64bit باشن.

نکته: در صورت حل نشدن مشکل با نصب معماری مناسب، فایل eclipse.ini رو که در کنار فایل اجرایی Eclipse تون هست رو باز کنید و بدنبال واژه –vm بگردید... بعد در زیر این واژه مسیر نصب شده Java رو جایگزینش کنید...

و یا برنامه Eclipse رو باز کنید و به مسیر Menu -> Prefecences -> Java -> Installed JREs برید و مسیرنصب شده Java رو بهش بدید...

4- اگر هنگام بازکردن برنامه Android Studio در صفحه loading/splash متوقف شد یکی از راه های زیر رو دنبال کنید:

- اتصالتون رو با اینترنت قطع کنید و مجدداً برنامه رو باز کنید.

- اگر گوشی به دستگاه متصل هست، از دستگاه جدا و مجدداً برنامه رو باز کنید.

- برنامه رو از طریق گزینه Run as administrator موجود در منوی راست کلیک باز کنید.

- مطعن بشید که محتوای ANDROID_HOME و ANDROID_SDK_HOME در environment variable موجود و بدرستی تنظیم شده باشن.

 

5- برای حل مشکل Cannot Create Android Virtual Device در AVD اندروید یکی از راه های زیر رو دنبال کنید:

- برنامه ها رو ببندید و مجدداً بازشون کنید. اکلیپس، AVD Manager, AS...

- در پنجره ساخت دیوایس، مطمعن بشید که نوع CPU/ABI رو انتخاب کردید.

- مطمعن بشید که متغیر ANDROID_SDK_HOME به path مناسب و بدون فاصله ای تنظیم شده باشه.

- مطمعن بشید که System Image مربوط به اون دیوایس رو نصب کردید. ARM EABI v7a یا Intel x86 Atom...

- مطمعن بشید که در نام دیوایس فاصله(space) وجود نداشته باشد.

- مطمعن بشید که دیوایسی با این نام وجود نداشته باشد.(duplicate)

- یک دیوایس رو Clone کنید و او رو Edit کنید.

- مطعمن بشید که نسخه API ای که انتخاب کردید با CPU/ABI انتخاب شده سازگار باشه.

- برنامه AVD Manager رو در خارج از محیط برنامه نویسی باز کنید.

- از اسکریپت monitor.bat موجود در پوشه tools اندروید SDK استفاده کنید.

 

6- برای راست چین(RTL) کردن متون فارسی در اندروید قبل از 4 میتونید از روش های زیر استفاده کنید:

- اگر به قوائد unicode مسلط هستید میتونید از RIGHT-TO-LEFT MARK استفاده کنید:

String myMixedString = "Test \u200F(تست)";

- تغییر مقدار gravity به مقدار right

- استفاده از HTML

 

7- اگر هنگام بازکردن برنامه Device Monitor اندروید با خطای An error has occured. See the log file مواجه شدید برای حلش یکی از راه های زیر رو دنبال کنید:

- برنامه رو ببندید و با کاربر Administrator یا root باز کنید... یا توسط run as administrator یا دستور sudo.

- Task Manager سیستم رو باز کنید و اگر برنامه monitior.exe باز هستش اون رو Kill/End کنید.

- برنامه SDK Manager رو باز کنید و جدیدترین پکیج Android SDK Tools رو دانلود و نصب کنید. بعد برنامه Device Monitor رو مجدداً باز کنید.

- اگر در نام account سیستم تون فاصله وجود داره(مثل Firstname Lastname)، باید account دیگه ای بسازید و همه فایلها رو به اونجا منتقل کنید و مجدداً نصب و تنظیمشون کنید!

 

8- برای حل مشکل Could not open Selected VM debug port (8700) در برنامه Device Monitor یکی از راه های زیر رو دنبال کنید:

- برنامه Device Monitor رو ببندید و توسط IDE بازش کنید. (Device Monitor رو نباید مستقیم باز کرد)

- همه برنامه ها رو بسته و Task Manager رو باز کنید. بعد adb رو Kill/End کنید. در آخر برنامه رو مجدداً باز کنید.

- Task Manager سیستم رو باز کنید و اگر برنامه monitior باز هستش اون رو Kill/End کنید.

- باید DDMS رو تنظیم کنید که کدوم VM رو debug کنه. یعنی بر روی کدوم system_process باید سوار بشه و کار کنه.

- ویندوز: به مسیر C:\WINDOWS\system32\drivers\etc برید و فایل hosts رو باز کنید و این مقدار 127.0.0.1 localhost رو داخلش وارد کنید. (اگر نیست)

- وارد تنظیمات DDMS بشید و Base local debugger port رو به 8701 تغییر بدید و فیلد Use ADBHOST رو هم تیک بزنید. در آخر value رو بذارید 127.0.0.1

- سیستم رو یکبار خاموش و روشن کنید.

- اگر Eclipse و Android Studio هر دو باز هستن، اونها رو ببندید و فقط یکی رو باز کنید. (چون هردو از یک منبع SDK استفاده می کنن)

 

9- با استفاده از ابزار Lint گوگل، پروژه اندروید تون رو برای پیدا کردن bug های پنهان/خفیف اسکن کنید.

- در اندروید استودیو کافیه به منوی Analyse -> Inspect Code برید و در پنجره باز شده Ok رو بزنید تا فعال بشه.

- یا کد زیر رو در فایل build.gradle بنویسید تا با هربار build، سیستم Lint بصورت خودکار فعال بشه:

lintOptions
{
   abortOnError true
}

 

10- اگر هنگام نصب برنامه APK اندروید با خطای There is a problem parsing the package مواجه شدید، راه های زیر رو بررسی کنید:
- احتمالاً نام برنامه رو تغییر دادید، پس به حالت اولش برگردونید.
- از مقدار minSdkVersion در فایل .gradle و سازگاریش با دستگاه رو مطمعن بشید.
- شاید نام برنامه رو بعد از Sign کردن تغییر دادید. (در Manifest نام رو اصلاح کنید)
- برنامه شما برای API بالاتر از دستگاه موردنظر کامپایل شده. (در Manifest درجه API رو پایین بیارید)
- شاید برنامه دسترسی INSTALL_PACKAGES رو نداره.
- مطمعن بشید که تیک Unknown Sources to allow installation of non Market Applications در Settings دستگاه فعال باشه.
- پکیج مورد نظر بروی SD-Card قرار داره و از اونجا داره نصب میشه. پس باید به حافظه داخلی/Phone منتقل و نصبش کنید.
- احتمالا پگیج Sign نشده.
- شاید برنامه رو در دایرکتوری ذخیره کردید که دسترسی های لازم رو نداره.
- برنامه بطور کامل دانلود نشده و پکیج ناقص هست.
- در برنامه از منابع سخت افزاری استفاده شده که دستگاه شما پیشتیبانیش نمی کنه.

 

11- نکته جریی: برنامه Android Studio برای اجرا شدن از JRE استفاده می کنه، اما برای کامپایل از Gradle استفاده میکنه. برنامه Gradle هم برای اجرا شدن از JRE استفاده می کنه، اما برای کامپایل جاوا از JDK (و دیگر کامپایلرهای مختص هر زبان) استفاده می کنه.

 

12- دلیل قفل شدن برنامه Android Studio هنگام باز کردن پروژه با پیام Gradle: resolve dependancies، عدم دسترسی Android Studio به مخازن گوگل هستش که بخاطر مشکلات شبکه یا تحریم بوجود میاد. راه حل:

- فایل gradle.properties رو باز کنید و برای HTTP و HTTPS پروک*&سی وارد کنید:

systemProp.http.proxyHost=<http proxy address>
systemProp.http.proxyPort=<http proxy port>
systemProp.https.proxyHost=<https proxy address>
systemProp.https.proxyPort=<https proxy port>
یا
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=8080

- یا وارد Preferences -> Gradle اندروید استودیو بشید و گزینه work offline رو تیک بزنید و مجدداً تلاش کنید.

- یا فایل build.gradle رو باز کنید و بجای jcenter() بنویسید mavencentral() و مجدداً تلاش کنید.

- یا سیستم رو یکبار خاموش و روشن کنید.

- یا چند دقیقه صبر کنید تا عملیات به پایان برسه.

- یا برنامه اندروید استودیو رو مجدداً نصب کنید.

- یا برنامه AntiVirus یا Firewall رو غیر فعال کنید و مجدداً تلاش کنید.

 

13- همیشه از واحد SP برای تعیین اندازه font و از واحد DP برای تعیین اندازه عناصر(و دیگر آیتم ها) استفاده کنید.

- نوع DP مبتنی بر اندازه density فیزیکی صفحه هستش.

- اما نوع SP با تغییر اندازه فونت دستگاه تنظیم میشه - یعنی توسط screen density و font size preference کاربر.
نکته: تغییر اندازه فونت دستگاه توسط کاربر از اندروید ICS به بعد امکانپذیره.
نکته 2: بدلیل محدودیت اندازه در toolbar برنامه، بهتره از DP استفاده بشه.

 

14- مفهوم Loose Coupling یعنی عدم وجود وابستگی در دسته ای از کلاس. یعنی متصل اما مستقل. یعنی افزایش flexibility و re-usability کد. یعنی استقلال در حین وابستگی. یعنی عدم وابستگی در روابط بین کلاس ها.

و مفهوم Tight Coupling یعنی وجود وابستگی سخت/تودرتو در دسته ای از کلاس. یعنی متصل و به هم وابسته. یعنی کاهش flexibility و re-usability کد. یعنی وابستگی در روابط بین کلاس ها.

 

15- نکته جزیی: جهت thread-safe کردن متدها کافیه از کلمه کلیدی synchronized در تعریف متد استفاده کنید.

public synchronized void myMethod()
{
   // ...
}

نکته: استفاده از کلمه کلیدی synchronized روی متد باعث میشه تا در هر لحظه فقط یک Thread متد رو اجرا کنه و تا پایان اجرای متد Thread دیگری متد رو اجرا نکنه.

 

16- یادتون باشه که تقدم اجرای initializer ها در یک کلاس همیشه بصورت: Static initializer -> Instance initializer -> Constructor هستش.

public class MyClass
{
   // Constructor initializer
   public MyClass()
   {
      // #3
   }

   // Static initializer
   static
   {
      // #1
   }

   // Instance/Object initializer
   {
      // #2
   }
}

در این حالت ابتدا بلوک initializer احرا خواهد شد و سپس بدنه متد سازنده.

 

17- سعی کنید متغیرهای کلاس رو در خارج از متد constructor آماده سازی/Initialize کنید. (اینها مقادیر پیشفرض دارن و حتی قبل از اینکه سازنده کلاس صدا زده بشه مقدار دهی می شوند. پس دوبار به اونها مقدار ندید! بعلاه خوانایی کلاس راحت تر و سریع تر انجام میشه)

 

 18- مفهوم و تفاوت Concurrency(همزمانی) و Parallel(موازی):

- پردازش Parallel نوعی از Concurrent هستش. درواقع Parallel زیرمجموعه Concurrency هستش.

- نوع Concurrent میتونه با یک پردازنده اعمال بشه (single/multi thread). اما نوع Parallel باید در چند پردازنده اعمال بشه. یعنی یک پردازنده به ازای هر پروسس.

نکته: عمل multi-threading هم زیر مجموعه parallelism محسوب میشه(اما Parallel programming نیست) و میتونه توسط یک یا چند پردازنده انجام بشه.

 

19- برای تولید خودکار APK هنگام Clean/Build کردن پروژه در Eclipse، کافیه به مسیر Window -> Preferences -> Android -> Build برید و گزینه Skip packaging and dexing untill export or launch رو تیک بزنید.

 

20- اگر در تولید فایل build.xml (اسکریپت Ant) با مشکل مواجه شدید، کافیه در خط فرمان دستور زیر رو بزنید تا مجدداً ایجاد بشه:

android update project -p ./ --subprojects
یا
android update project -p ./

فایل اسکریپت android در مسیر <YOUR-ANDROID-SDK-HOME>/tools قرار داره.

 

21- برای حل مشکل ADB در برقراری ارتباط شاید لازم باشه در بعضی از دستگاه ها MTP (Media Transfer Protocol) فعال بشه و در بعضی دیگر PTP (Picture Transfer Protocol).

 

22- هنگام دریافت خطای failed to load با Android Virtual Device مطمعن بشید که ANDROID_HOME در PATH موجود و درست تنظیم شده باشه.

 

23- همیشه wire-frame یا mockup طرح UI رو در اندازه 360px x 568px یا همون MDPI 1.0x طراحی کنید. و سایز آیکون هارو در اندازه 24dp یا 48dp بزنید.

 

24- تحت هیچ شرایطی مقدار NULL رو return نکنید. درعوض رشته خالی "" یا 0 یا آرایه خالی [] بازگشت بدید.

 

25- برای فعالسازی Proguard در اندروید استودیو(Gradle) فایل build.gradle موجود در app رو باز و دستورات زیر رو بنویسید:

android
{
   buildTypes
   {
      release
      {
         minifyEnabled true
         proguardFiles getDefaultProguardFile(‘proguard-android.txt'), 'proguard-rules.pro'
      }
   }
}

نکته: درصورتیکه قابلیت shrinkResources هم در این فایل true باشه، resource های پروژه هم shrink خواهند شد.

 

26- فرمول محاسبه حافظه JVM:

JVM memory = JVM Max Heap(-Xmx) + JVM Perm Size(-XX) + NumberOfConcurrentThreads * StackSize(-Xss) + OtherRequiredMemory(JIT, NIO, JNI...)

 

27- نکته جزیی: دستورات  wait(), notify() و notifyAll() همیشه باید در کدهای synchronize اجرا بشن.

 

28- تشریح ClassNotFoundException و NoClassDefFoundError:

- مشکل ClassNotFoundException از نوع Exception هستش و زمانی پرتاب میشه که برنامه جاوا بصورت Dynamic سعی در load کردن کلاس موردنظر حین Run-time از مسیر CLASSPATH کنه اما نتونه پیداش کنه.

- مشکل NoClassDefFoundError از نوع Error هستش و زمانی بوجود میاد که کلاس موردنظر در مسیر CLASSPATH حین Compile-time وجود داره اما حین Run-time وجود نداره.

 

29- آیا میدونید هنگام استفاده از اپراتورهای compound assignment (مثل += -= *= /= %=) یک عمل type-casting هم در پشت پرده صورت میگیره؟

 

30- برای حل مشکل java.lang.NoClassDefFoundError هنگام اجرای برنامه تولید شده توسط Android Studio یکی از راه های زیر رو دنبال کنید:

- به مسیر Menu -> File -> Settings -> Build, Execution, Deployment ->Instant Run در برنامه Android Studio برید و قابلیت Instant Run رو خاموش کنید.

- پروژه رو یکبار Clean کنید و مجدداً build کنید.

- نسخه مقدار classpath در gradle رو کاهش بدید و مجدداً build کنید.

- کتابخانه compile 'com.android.support:multidex:1.0.1' رو به پروژه اضافه و مجدداً build کنید.

 

31- برای حل مشکل IllegalArgumentException: Unable to locate adb در برنامه Android Studio راه های زیر رو دنبال کنید:

- اگر از برنامه های AntiVirus استفاده می کنید، به قسمت Quarantine برید و فایل adb.exe رو آزاد کنید. بعد AntiVirus رو خاموش کنید.

- وارد SDK Manager بشید و پکیج Android SDK Tools رو نصب کنید.

- پکیج Platform-Tools رو توسط SDK Manager پاک کنید و فایلهای Platform-Tools موجود در مسیر SDK رو حذف کنید. بعد مجدداً نصبش کنید.

- به Control Panel برید و مسیر System -> Advanced System settings -> Advanced tab -> Settings-> Advanced tab -> Change رو طی کنید. حالا مقدار initial و Maximum رو به نصف کاهش بدید. (این مقدار تعیین کننده حافظه مجازی/SWAPING هستش)

- در Android Studio به مسیر Tools -> Android -> SDK Manager -> Launch Standalone Sdk manager برید و پکیج هایی که نصب نشده رو نصب کنید.

- شاید لازم باشه فایل adb.exe رو در مسیر X:\Users\YOUR-WINDOWS-USERNAME\AppData\Local\Android\SDK\Platform-Tools کپی کنید.

 

32- برای حل مشکل system_process E/Surface: getSlotFromBufferLocked: unknown buffer راه های زیر رو دنبال کنید:

1- اگر در حین runtime برنامه درخواست permission ای میدید، بهتره در فایل manifest در قسمت uses-permission قید کنید.
2- اگر از اندروید 6.0.0 (Marshmallow) استفاده می کنید به اندروید 6.0.1 upgrade کنید.
3- اگر از background task استفاده می کنید، ابتدا باید task مورد نظر finish بشه و بعد context رو ببندید. یا از getApplicationContext بجای activityContext استفاده کنید.
4- برنامه Android Studio و Emulator رو ببندید و مجدداً باز کنید.
5- شاید فایل java اکتیویتی رو حذف کردید اما xml ش رو حذف نکردید.

 

33- درصوت لود نشدن محتوای لیست(بخاطر مسایل تحریم) SDK Manager به مخازن SDK کمکی موجود در اینترنت مراجعه و آدرس لینک فایلهای XML رو کپی کنید سپس داخل منوی Addon Sites یا زبانه SDK Update Sites برنامه SDK Manager وارد کنید. بعد مجدداً لیست رو refresh کنید. https://mirrors.zzu.edu.cn/android/repository/

 

34- همیشه محتوای فایلهای SharedPreferences رو قبل از ذخیره کردن رمزنگاری کنید تا توسط دیگر برنامه ها یا کاربر root قابل خواندن نباشن.

 

35- تفاوتهای new String("...") و String در جاوا:

اولی رشته ای از نوع literal string هستش (چیزی شبیه به simple string یا premitive ها)
دومی رشته ای از نوع OBJECT هستش

اولی در قسمت method area حافظه ذخیره میشه (یا همون class area)
دومی در قسمت heap حافظه ذخیره میشه (instance خود شی، نه متغیرش)
enlightenedنکته: حوزه ی حافظه Heap برنامه وابسته به runtime برنامست. یعنی با شروع برنامه اشغال و با بستن برنامه تخلیه میشه.

در اولی اگر صدها رشته با یک مقدار ثابت وجود داشته باشه، همگی حین compile یکی و merge میشن و هنگام runtime به یک آدرس در حافظه ارجاع داده میشن
در دومی اگر صدها شی رشته با یک مقدار ثابت وجود داشته باشه، هر کدوم هنگام runtime به یک آدرس جداگانه در حافظه ارجاع داده میشن
enlightenedنکته: مگر اینکه صراحتاً دستور intern() استفاده بشه.

String str2 = new String("Hello").intern();

در اولی دستوراتی مثل substring روی "خود" رشته اعمال میشه
در دومی دستوراتی مثل substring روی "کپی" دیگری از شی اعمال میشه!

اولی حین compile-time پردازش و اعمال میشه
دومی حین run-time پردازش و اعمال میشه

اولی سبک تر و پرفورمنسش بالاتره
دومی سنگین تر و پرفورمنسش پایین تره

 

36- نکته جزیی: درصورتی که از javadoc JDK 1.7 استفاده می کنید و از استایل صفحات HTML (مستندات) تولید شده راضی نیستید، میتونید از این Stylesheet استفاده کنید.

 

37- درصورتی که از قابلیت های Google Framework(یا همون Google API) استفاده نمی کنید، نیاز به دانلود و نصب system image های Google و Google API ندارید.

 

38- نکته جزیی: وظیفه نوشتن کدهای تست برای Unit Testing بعهده فرد برنامه نویس هستش نه فرد Tester. زیرا:

- بدلیل حفظ مالیکت کدها/پروژه، Tester نباید به سورس پروژه دسترسی داشته باشه.

- بدلیل مسایل امنیتی و کاهش تهدیدها، Tester نباید به داخل کدها و مکانیزم سیستم دسترسی داشته باشه.

- همچنین Tester قادر نیست به همه ابزارها، سبکها و زبانهای مختلفی که در پروژه استفاده شده مسلط بشه و test case طراحی کنه.

- تنها برنامه نویس هستش به کدهایی که پیاده سازی کرده مسلطه و test case رو در کمترین زمان با بالاترین کیفیت تولید میکنه.

 

39- در صورت بروز خطای Could not resolve all dependencies for configuration ':classpath' در نرم افزار Gradle یکی از راه های زیر رو دنبال کنید:

- مطمعن بشید که ارتباطتون با اینترنت برقرار باشه.

- مطمعن بشید که JDK نسخه 1.8.0 یا جدیدتر روی سیستم نصب باشه.

- اگر از pr0xi داخل فایل gradle.properties یا VPN استفاده می کنید اونرو خاموش کنید و ارتباط اینترنتی تون رو قطع و وصل کنید.

- آدرس repository داخل فایل build.gradle رو به یکی از مخازن زیر تغییر بدید:

repositories {jcenter()}
repositories {mavencentral()}
repositories {google()}
repositories {maven {url 'http://repo1.maven.org/maven2'}}
repositories {maven {url "https://plugins.gradle.org/m2/"}}

repositories {ivy {url "http://repo.mycompany.com/repo"}}

- جدیدترین نسخه نرم افزار JDK رو دانلود و نصب کنید.

- توسط دستور gradle build --refresh-dependencies همه dependency هارو refresh کنید.

- در ویندوز: وارد تنظیمات Network and sharing center سیستم بشید. در سمت چپ گزینه Change adapter setting رو کلیک کنید. روی آیکون network connection تون کلیک راست و گزینه Properties رو انتخاب کنید. در لیست باز شده دوباری روی گزینه IPv4 کلیک کنید. در پنجره باز شده گزینه Use the following dns server addresses رو انتخاب و مقادیر زیر رو وارد کنید:

Preferred DNS server: 208.67.222.222
Alternate DNS server: 208.67.220.220
یا
Preferred DNS server: 8.8.8.8
Alternate DNS server: 8.8.4.4

 

40- جهت تنظیم بهتر Push notification و جلوگیری از باگهای احتمالی حتماً این مقاله کوتاه رو مطالعه کنید.

 

مقالات مرتبط

نکات و اصول مهم در برنامه نویسی Java/Android

#2 - نکات و اصول مهم در برنامه نویسی Java/Android

#3 - نکات و اصول مهم در برنامه نویسی Java/Android

#4 - نکات و اصول مهم در برنامه نویسی Java/Android

#5 - نکات و اصول مهم در برنامه نویسی Java/Android

#7 - نکات و اصول مهم در برنامه نویسی Java/Android

نظرات (۱)

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