<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های سعید حسن خان | saeed hasankhan</title><link>https://virgool.ir/feed/@saeedhassankhan.g</link><description>علاقه مند به دنیای تکنولوژی و برنامه نویسی</description><language>fa</language><pubDate>2026-11-12 17:11:09</pubDate><image><url>https://files.virgool.ir/upload/users/95333/avatar/As60am.jpeg</url><title>سعید حسن خان | saeed hasankhan</title><link>https://virgool.ir/@saeedhassankhan.g</link></image><item><title>برنامه نویسی پایتون در شیراز از کلاس تا دوره های مختلف</title><link>https://virgool.ir/@saeedhassankhan.g/چطوری-در-شیراز-برنامه-نویس-پایتون-شدم-کلاس-حضوری-آری-یا-نه-wxzkv7ecbf4r</link><description>شیراز و مسیر برنامه نویس شدن منشاید شما هم اگر اول راه برنامه‌نویسی پایتون هستین حال من رو در چند سالِ پیش درک کنید که چقدر بین آموزش های مختلف سردرگم شده بودم و بین توصیه‌های مختلف و هزینه‌های چند میلیونی نمیدونستم باید کدوم گزینه رو انتخاب کنم مخصوصا اینکه من محل زندگیم شیراز بود و حتی برای شرکت توی کلاس هایی حضوری و استادهای خوب توی شیراز محدودیت هم داشتم و با کلی به در و دیوار خوردن تونستم مسیر خودم رو پیدا کنم و از این راه کسب درآمد کنم و حتی استخدام بشم.توی این متن سعی کردم تجربه خودم رو به اشتراک بذارم شاید برای کسایی که به دنبال آموزش مخصوصا پایتون و بصورت حضوری یا حتی آنلاین هستن و قراره کلی هزینه کلاس بدن کمک کننده باشه.برای آموزش پایتون قبل از هرچیزی من به این نتیجه رسیدم که بین کلاس های حضوری و آنلاین و پکیج من میتونم خودخوان هم یادبگیریم ولی مسئله بعدیم این بود که چه دوره ای رو باید شروع کنم که چون زبان انگلیسیم خوب بود رفتم سراغ سایت هایی که بصورت انگلیسی آموزش پایتون و دوره های اون رو داشتن که به دوتا سایت معروف رسیدم udemy و coursera و از سطح و کیفیت دوره های آموزشی ای که برای پایتون داشتن به وجد اومدم ولی مشکل بعدی هزینه و خرید این دوره‌ها از این سایت‌ها بود که با ایرانی بودن مشکل داشتن ولی باز یه راه دیگه براش پیدا کردم:  بصورت خیلی جالب میتونید اون دوره ای که توی این سایت ها میبینید رو عنوانش رو یادداشت کنید مثلا به این شکل Coursera – Python 3 Programming Specialization 2024-9Coursera – Python for Everybody Specialization 2024-7Udemy - Python Coursesو حالا که فهمیدین اسم اون دوره آموزشی پایتون دقیقا چی هست حالا توی گوگل به این شکل سرچش کنید Coursera – Python 3 Programming Specialization 2024-9 دانلودCoursera – Python for Everybody Specialization 2024-7 دانلودو میبینید که کلی هموطن عزیز اومدن و این دوره‌های آموزشی که با هزینه‌های بالایی بودن رو بصورت رایگان  برای دانلود قرار دادن.اما این روش واسم معایبی هم داشت، مثلا بارها بخاطر صحبت‌های دیگران و سختی راه نامید شدم و برنامه نویسی رو  قصد داشتم بذارم کنار و با کندی ادامه میدادم چیزی که اگر یه مربی خوب یا یه استاد دلسوز در کنارم بود کمتر اتفاق میوفتاد و باعث میشد این دوره‌های پایتون و برنامه نویسی رو حتی خیلی سریع‌تر طی کنم . البته همیشه به خودم امید و انگیزه میدادم و سعی میکردم آدم‌های موفق و درآمدهای بالا رو توی ذهنم بیارم و باز برگردم به میدون و اگر یکجایی هم خسته‌م میشد به خودم سخت نمیگرفتم و یکم از موضوع دور میشدم تا انرژیم برگرده و به این مسیر بصورت بلند مدت نگاه میکردم، نه چیزی که خیلی سریع قراره منو پولدار کنه.عیب بعدی این بود که وقتی به مشکل میخوردم و سوالاتی توی انجام تمرین‌ها برام پیش میومد کسی نبود که ازش راهنمایی بگیرم و یا اینکه اگر نیاز داشتم یک حوزه رو بیشتر تمرین کنم، امکانش نبود چون اون دوره پایتون ضبط شده بود و بعدا که با سایت میدلرن آشنا شدم و دیدم دغدغه‌شون برای آموزش دقیقا همین چیزاست خیلی حسرت خوردم که کاش زودتر پیداشون کرده بودم.برای حل این مشکل این اواخر خیلی از chatgpt کمک گرفتم و اون زمان‌ها هم ایده‌هایی که فکر میکردم جذاب و پولسازه رو سعی میکردم انجام بدم و برای خودم ددلاین تعریف میکردم که حتما توی این ماه اینکارو باید انجام بدی و همین کلی برام انگیزه ایجاد میکرد.مشکل بعدیم که خودش رو بعدا خیلی نشون داد کم بودن دایره ارتباطاتم بود که بخشیش بخاطر همین تنها و خودخوان بودنم بود که چون کلاسی شرکته نکرده بودم طبعا نه من کسی رو میشناختم نه کسی من رو برای همین تصمیم گرفتم اکانت لینکدینم رو تقویت کنم و اونجا آدم‌های کاربلد و درست رو پیدا کنم, دنبالشونم کنم و ازشون سوال بپرسم پست‌هاشون رو لایک کنم، منم با تولید محتوا خودم رو به بقیه بشناسونم و سعی کنم دایره ارتباطاتم رو اینجوری گسترش بدم.در کنارش هم سعی کردم محیط های کار اشتراکی‌ای که در شیراز هست رو پیدا کنم و ازشون برای تمرکز بیشتر روی کار و آشنا شدن با افرادی مثل خودم نهایت استفاده رو ببرم.همینطور داخل سایت‌هایی که ایونت برگذار میکنن هم ثبت‌نام کردم (البته ممکنه اگر مثل من شیراز زندگی میکنید یا ساکن تهران نیستید از این ایونت ها کمتر باشه براتون ) در حال تکمیل ....امیدوارم این مطلب براتون مفید بوده باشه و با لایک و کامنت بهم انگیزه بدید بازم تجربیاتی که شاید برای برخی کمک کننده باشه رو بنویسم.</description><category>سعید حسن خان | saeed hasankhan</category><author>سعید حسن خان | saeed hasankhan</author><pubDate>Wed, 13 Nov 2024 22:20:20 +0330</pubDate></item><item><title>من; شرکت یک نفره</title><link>https://virgool.ir/@saeedhassankhan.g/من-شرکت-یک-نفره-wopdnzdwfdn1</link><description>من; شرکت یک نفرهشاید خیلی هارو توی زندگی دیده باشیم که یکی از رویا هاشون داشتن یک بیزینس ، استارت آپ، شرکت و  یک نقش تاثیر گذار در مسیر زندگی باشه و نمیشه منکر جذابیت این رویا شد ، و چه بسا خیلی ها هم علاوه بر تلاش های بسیار زیاد و یار بودن بخت باهاشون در این مسیر طعم موفقیت رو میچشن، اما روی صحبت من از سمت دیگر ماجراست ، شخصی که شاید پایین ترین رده یک سازمان، باشه و به ظاهر و از یک نمای بیرونی صرفا یک حقوق بگیر و کارمند به نظر برسه، اما از جهتی دیگه اون شخص یک شرکت یک نفره ست ، شرکتی که بزرگ ترین سرمایه فعلیش خودش و مهارت های خودش هست ، و بالتبع در حال حاظر در رقابت با شرکت های یک نفره دیگه باید برای خودش مزیت رقابتی ایجاد کنه اما این مزیت رقابتی چی میتونه باشه ؟ شاید مدل ذهنی من در این رابطه بتونه تا حدی کمک کننده باشه، من به واسطه شغلم که یک برنامه نویس و توسعه دهنده هستم، به نوعی بیشتر اوقاتم رو با یک ماشین در ارتباطم ، ماشینی که زبان صحبت کردن باهاش جاوا هست و جدیدا کاتلین هم یادگرفته و من رو هم مجبور کرده زبون صحبت باهاش رو یاد بگیرم تا بتونیم باهاش بهتر ارتباط برقرار کنم، نیاز هاشو درک کنم و بدقلقی هایی که میکنه و معروفه با باگ رو بفهمم و رضایتش رو جلب کنم، اما از جهتی همه ما انسان ها نوعی ماشین هستیم با این تفاوت که برخلاف کامپیوتر های زبون بسته ، دارای پیچیدگی های به شدت بیشتری هستیم ، دارای احساسیم ، هر کدوممون بعلاوه زبان native ای که داریم بخاطر پیشینه فرهنگی و تربیتی و تحصیلی ، زبان منحصر به فرد خودمون رو پیدا کردیم پس قبل از هرچیز باید با ماشینی به اسم &#34;من&#34; بیشتر آشنا بشیم که اسمی که روی این فرایند به نوعی گذاشته شده، خودشناسی هست ، از جهتی دیگه ما در طول روز و در مسیر شغلی با چندین و چند ماشین پیشرفته در ارتباطیم که نحوه ارتباط باهوشون، توانایی قانع کردنشون و راهنمایی گرفتن از اونها مسیر موفقیت یا شکست مارو تعیین میکنه   و مهمترین سوالی که اینجا ایجاد میشه، برای توسعه این مهارت ها باید چه کاری انجام داد ؟خب برای حوزه اول که احتمالا اگر یک مدیر صرف نیستیم ، عموما برای کسب درآمد در حال کار با یک ماشین هستیم، که میتونه این ماشین یک گوشی موبایل و برنامه نویسی برای اون باشه تا راننده یک کامیون ،که راه های زیادی برای یادگیری و هم صبحتی بهتر با اون ماشین به لطف اینترنت و حتی کلاس ها و افراد خبره مهیا هست و صرفا کمی اراده و همت نیاز هست .اما حوزه دوم که با ماشین هایی از جنس انسان سرو کار داریم ، بخاطر اینکه اصولا انسان ها 0 و 1 ای نیستن احتمالا در درکشون یا حتی درک خودمون با کوهی از ابهام ، چالش و تضاد روبرو بشیم و این صرفا با تقویت مهارت های نرم ، خودشناسی و ... به مرور فضا رو شفاف تر و زیباتر میکنه . امیدوارم اگر این مطلب رو دوست داشتین و تمایل داشتین مهارت های نرم خودتون رو توسعه بدین ، سری به سایت جذاب متمم بزنید و از مطالب مفیدش بهره مند بشید(برای شروع مهارت یادگیری رو پیشنهاد میدم) و اگر دوست داشتین با موسس این سایت بیشتر آشنا بشین، این گفتگو با محمد رضا شعبانعلی تماشا کنید.ممنون از وقتی که صرف خوندن این مطلب کردین و لایک هایی که باعث دلگرمیم میشن.</description><category>سعید حسن خان | saeed hasankhan</category><author>سعید حسن خان | saeed hasankhan</author><pubDate>Sat, 26 Feb 2022 23:26:14 +0330</pubDate></item><item><title>اینترو (intro) در اندروید بدون نیاز به استفاده از لایبراری</title><link>https://virgool.ir/coderlife/اینترو-intro-در-اندروید-بدون-نیاز-به-استفاده-از-لایبراری-omyqnre8wsqa</link><description>شاید شما هم مثل من از اون دسته افرادی باشید که خیلی دوست ندارن اپلیکیشنشون رو پر بکنن از لایبراری های متفاوت و سعی دارن تا جایی که میشه لایبراری های مورد نیاز رو خودشون بنویسن تا هم یکسری تکنیک هارو یادبگیرن و هم اینکه از افزایش حجم اپ و مشکلات تداخل لایبراری ها و deprecate شدنشون دوری کننخب بریم سر اصل مطلب : برای پیاده سازی این پروژه به سه فایل اصلی نیاز داریم :1 : ScreenSlidePagerActivity این فایل قراره توی نمایش اسلاید ها و swipe کردن بینشون با استفاده از viewpager2 بهمون کمک کنه :public class ScreenSlidePagerActivity extends FragmentActivity {&#xA;    /**&#xA;     * The number of pages (wizard steps) to show in this demo.&#xA;     */&#xA;    private static final int NUM_PAGES = 3;&#xA;&#xA;    /**&#xA;     * The pager widget, which handles animation and allows swiping horizontally to access previous&#xA;     * and next wizard steps.&#xA;     */&#xA;    private ViewPager2 viewPager;&#xA;    private TabLayout tabIndicator;&#xA;&#xA;    /**&#xA;     * The pager adapter, which provides the pages to the view pager widget.&#xA;     */&#xA;    private FragmentStateAdapter pagerAdapter;&#xA;&#xA;    @Override&#xA;    protected void onCreate(Bundle savedInstanceState) {&#xA;        super.onCreate(savedInstanceState);&#xA;        setContentView(R.layout.activity_screen_slide);&#xA;&#xA;        // Instantiate a ViewPager2 and a PagerAdapter.&#xA;        viewPager = findViewById(R.id.pager);&#xA;        pagerAdapter = new ScreenSlidePagerAdapter(this);&#xA;&#xA;        tabIndicator = findViewById(R.id.tabIndicator);&#xA;        viewPager.setAdapter(pagerAdapter);&#xA;//add animation to items when transferring&#xA;        viewPager.setPageTransformer(new PageTransformer());&#xA;//show state of slides with dots in bellow of page&#xA;        new TabLayoutMediator(tabIndicator , viewPager , (tab , position) -&gt; {}).attach();&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onBackPressed() {&#xA;        if (viewPager.getCurrentItem() == 0) {&#xA;            // If the user is currently looking at the first step, allow the system to handle the&#xA;            // Back button. This calls finish() on this activity and pops the back stack.&#xA;            super.onBackPressed();&#xA;        } else {&#xA;            // Otherwise, select the previous step.&#xA;            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);&#xA;        }&#xA;    }&#xA;&#xA;    /**&#xA;     * A simple pager adapter that represents 3 ScreenSlidePageFragment objects, in&#xA;     * sequence.&#xA;     */&#xA;    private class ScreenSlidePagerAdapter extends FragmentStateAdapter {&#xA;        public ScreenSlidePagerAdapter(FragmentActivity fa) {&#xA;            super(fa);&#xA;        }&#xA;&#xA;        @Override&#xA;        public Fragment createFragment(int position) {&#xA;            switch (position) {&#xA;                case 0:&#xA;                    return ScreenSlidePageFragment.getInstance(&#34;#e69597&#34;, R.string.intro_1, R.drawable.settings);&#xA;                case 1:&#xA;                    return ScreenSlidePageFragment.getInstance(&#34;#ceb5b7&#34;, R.string.intro_2, R.drawable.growth);&#xA;            }&#xA;            return ScreenSlidePageFragment.getInstance(&#34;#b5d6d6&#34;, R.string.intro_3, R.drawable.jump);&#xA;        }&#xA;&#xA;        @Override&#xA;        public int getItemCount() {&#xA;            return NUM_PAGES;&#xA;        }&#xA;    }&#xA;}2 : ScreenSlidePageFragmentاین فایل که درواقع همون اسلاید های اینترو رو، که شامل یک عکس و یک متن هستن رو شامل میشه public class ScreenSlidePageFragment extends Fragment {&#xA;&#xA;    public static  ScreenSlidePageFragment getInstance(String backgroundColor  , int desc , int iconRes){&#xA;        ScreenSlidePageFragment frag = new ScreenSlidePageFragment();&#xA;        Bundle bundle = new Bundle();&#xA;        bundle.putString(&#34;color&#34; ,  backgroundColor);&#xA;        bundle.putInt(&#34;desc&#34; , desc);&#xA;        bundle.putInt(&#34;icon&#34; , iconRes);&#xA;        frag.setArguments(bundle);&#xA;        return frag;&#xA;    }&#xA;&#xA;    @Override&#xA;    public View onCreateView(LayoutInflater inflater, ViewGroup container,&#xA;                             Bundle savedInstanceState) {&#xA;        ViewGroup rootView = (ViewGroup) inflater.inflate(&#xA;                R.layout.activity_screen_slides, container, false);&#xA;&#xA;&#xA;        TextView txt = rootView.findViewById(R.id.txt);&#xA;        ImageView img = rootView.findViewById(R.id.imgIcon);&#xA;        LinearLayout lytRoot = rootView.findViewById(R.id.root);&#xA;&#xA;&#xA;        String col = getArguments().getString(&#34;color&#34; , &#34;#ffffff&#34;);&#xA;        int iconRes = getArguments().getInt(&#34;icon&#34;);&#xA;        int desc = getArguments().getInt(&#34;desc&#34;);&#xA;&#xA;&#xA;        img.setImageResource(iconRes);&#xA;        txt.setText(desc);&#xA;        lytRoot.setBackgroundColor(Color.parseColor(col));&#xA;&#xA;        return rootView;&#xA;    }&#xA;&#xA;    @Override&#xA;    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {&#xA;        super.onViewCreated(view, savedInstanceState);&#xA;    }&#xA;}خب حالا میرسیم به قسمت شیرین ماجرا و هندل کردن انیمشن های آیتم های صفحه که توسط این فایل انجام خواهد شد :3 : PageTransformerpublic class PageTransformer implements ViewPager2.PageTransformer {&#xA;    private static final float MIN_SCALE = 0.85f;&#xA;    private static final float MIN_ALPHA = 0.5f;&#xA;&#xA;&#xA;&#xA;    @Override&#xA;    public void transformPage(@NonNull View view, float position) {&#xA;&#xA;        int pageWidth = view.getWidth();&#xA;        int pageHeight = view.getHeight();&#xA;&#xA;        ImageView icon = view.findViewById(R.id.imgIcon);&#xA;        TextView txtDesc = view.findViewById(R.id.txt);&#xA;&#xA;        if (position &lt; -1) { // [-Infinity,-1)&#xA;            // This page is way off-screen to the left.&#xA;            view.setAlpha(0f);&#xA;&#xA;        } else if (position &lt;= 1) { // [-1,1]&#xA;            // Modify the default slide transition to shrink the page as well&#xA;            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));&#xA;&#xA;            float vertMargin = pageHeight * (1 - scaleFactor) / 2;&#xA;            float horzMargin = pageWidth * (1 - scaleFactor) / 2;&#xA;            if (position &lt; 0) {&#xA;&#xA;                view.setTranslationX(horzMargin - vertMargin / 2);&#xA;            } else {&#xA;&#xA;                view.setTranslationX(-horzMargin + vertMargin / 2);&#xA;            }&#xA;            icon.setRotation(position * 60);&#xA;            icon.setTranslationX(position * 500);&#xA;            txtDesc.setTranslationX(position * 1500);&#xA;&#xA;            // Scale the page down (between MIN_SCALE and 1)&#xA;            //view.setScaleX(scaleFactor);&#xA;            //view.setScaleY(scaleFactor);&#xA;&#xA;            // Fade the page relative to its size.&#xA;           /*view.setAlpha(MIN_ALPHA +&#xA;                    (scaleFactor - MIN_SCALE) /&#xA;                            (1 - MIN_SCALE) * (1 - MIN_ALPHA));&#xA;*/&#xA;            view.setAlpha(1f);&#xA;        } else { // (1,+Infinity]&#xA;            // This page is way off-screen to the right.&#xA;            view.setAlpha(0f);&#xA;        }&#xA;&#xA;    }&#xA;}نکته پایانی : در فایل آخر یکسری از خطوط کد کامنت شدن که میتونست برای خوانایی بهتر کد و تمیز تر بودنش پاک بشن ولی به نظرم اومد وجودشون و کمی بازی کردن باهاش میتونه کارهای جالب تری رو خلق کنه امیدوارم بتونه مفید باشه براتون ❤️سورس پروژه در گیت هابمنابع : android pager with dots , screen slides</description><category>سعید حسن خان | saeed hasankhan</category><author>سعید حسن خان | saeed hasankhan</author><pubDate>Fri, 13 Aug 2021 18:31:45 +0430</pubDate></item><item><title>استفاده از Room در اندروید</title><link>https://virgool.ir/@saeedhassankhan.g/استفاده-از-room-در-اندروید-ylml0kgdqcxs</link><description>در گذشته‌های نه چندان دور اگر یه توسعه‌دهنده‌ اندروید میخواست با دیتابیس کار کنه مجبور بود با خیلی از کارها مثل ساختن table و ذخیر کردن اطلاعات بصورت دستی و کوئری های مختلف کارشو پیش ببره اما با اومدن کتابخونه هایی مثل Room این کارا تا حد زیادی ساده تر شدن.قبل از شروع کار نیاز داریم که لایبراری های زیر رو به پروژه و در قسمت dependencies فایل build.gradle اپمون  اضاف کنیم.def room_version = &#34;2.2.6&#34;&#xA;implementation &#34;androidx.room:room-runtime:$room_version&#34;&#xA;kapt &#34;androidx.room:room-compiler:$room_version&#34;&#xA;// optional - Kotlin Extensions and Coroutines support for Room&#xA;implementation &#34;androidx.room:room-ktx:$room_version&#34;حالا وقته آشنا شدن با قسمت‌های مختلف Room  هست :@Entity@Entity&#xA;class Product : Serializable {&#xA;&#xA;    @PrimaryKey(autoGenerate = true)&#xA;    var id = 0&#xA;&#xA;    @ColumnInfo(name = &#34;name&#34;)&#xA;    var name: String? = null&#xA;&#xA;    @ColumnInfo(name = &#34;desc&#34;)&#xA;    var desc: String? = null&#xA;&#xA;} این قسمت مشخصات table ای که لازم داریم رو تعیین میکنه @Dao(data access objects)@Dao&#xA;interface ProductDao {&#xA;    @get:Query(&#34;SELECT * FROM product&#34;)&#xA;    val all: List&lt;Product?&gt;?&#xA;&#xA;    @Insert&#xA;    fun insert(product: Product?)&#xA;&#xA;    @Delete&#xA;    fun delete(product: Product?)&#xA;&#xA;    @Update&#xA;    fun update(product: Product?)&#xA;}این قسمت وظیفه ورود اطلاعات، حذف و ... رو بر عهده داره.حالا موقع به کار بردن دوتا کلاس بالا هستش : در اینجا به دوتا کلاس جداگونه دیگه هم احتیاج داریم که یکی وظیفه ارتباط با دیتابیس یا ساخت یک access point رو بر عهده داره و دومی وظیفه ساخت دیتابیس.@Database(entities = [Product::class] , version = 1)&#xA;public abstract class AppDatabase : RoomDatabase() {&#xA;    abstract fun productDao(): ProductDao? &#xA;}class DatabaseClient private constructor(mCtx: Context) {&#xA;    private val mCtx = mCtx&#xA;    val appDatabase: AppDatabase = Room&#xA;        .databaseBuilder(mCtx, AppDatabase::class.java, &#34;databse_name&#34;)&#xA;        .build()&#xA;&#xA;    companion object {&#xA;        private var mInstance: DatabaseClient? = null&#xA;&#xA;        @Synchronized&#xA;        fun getInstance(mCtx: Context): DatabaseClient? {&#xA;            if (mInstance == null) {&#xA;                mInstance =  DatabaseClient(mCtx)&#xA;            }&#xA;            return mInstance&#xA;        }&#xA;    }&#xA;}در این کلاس دوتا نکته وجود داره : 1: برای اینکه ساخت هرباره یک object از DatabaseClient به اصطلاح expensive هست و کمی کاهش سرعت در اپ رو میتونه ایجاد کنه از دیزاین‌پترن Singleton استفاده شده تا فقط یکبار object ایجاد بشه و بار های بعدی از دیتای cache شده استفاده بشه.2: برای استفاده از دیتابیس از main Thread برنامه نمیتونیم استفاده کنیم چرا که هم باعث قفل شدن لحظه‌ای برنامه میشه و هم اینکه سیستم‌عامل اجازه این کارو نمیده و حتما باید از thread جداگونه‌ای استفاده بشه برای همین موضوع از Synchronized@  استفاده کردیم تا ترد‌های مختلف هم‌زمان نتونن از دیتابیس استفاده کنن و داده ها با اختلال روبرو نشن. حالا موقع استفاده از کارهاییه که انجام دادیم : ایجاد یک داده جدید در table product var thread = Thread(Runnable {&#xA;    var product = Product();&#xA;    product.name = &#34;apple&#34;&#xA;    product.desc = &#34;delicious apples from Semirom of Iran&#34;&#xA;    DatabaseClient.getInstance(context)?.appDatabase!!&#xA;        .productDao()!!&#xA;        .insert(product)&#xA;})&#xA;thread.start()خلاصه : ما در واقع چهار کلاس اصلی ایجاد کردیم که Product (ایجاد مشخصات تیبل), ProductDao (ایجاد ، حذف ، اپدیت آبجکت های تیبل),DatabseClient  ( ساخت دیتابیس), AppDatabase (ایجاد رابط برای ارتباط با دیتابیس)  </description><category>سعید حسن خان | saeed hasankhan</category><author>سعید حسن خان | saeed hasankhan</author><pubDate>Thu, 25 Mar 2021 10:09:50 +0430</pubDate></item></channel></rss>