একটি উন্নত উইজেট তৈরি করুন

এই পৃষ্ঠাটি একটি ভাল ব্যবহারকারীর অভিজ্ঞতার জন্য আরও উন্নত উইজেট তৈরি করার জন্য প্রস্তাবিত অনুশীলনগুলি ব্যাখ্যা করে৷

উইজেট বিষয়বস্তু আপডেট করার জন্য অপ্টিমাইজেশান

উইজেট সামগ্রী আপডেট করা গণনাগতভাবে ব্যয়বহুল হতে পারে। ব্যাটারি খরচ বাঁচাতে, আপডেটের ধরন, ফ্রিকোয়েন্সি এবং সময় অপ্টিমাইজ করুন।

উইজেট আপডেটের প্রকার

একটি উইজেট আপডেট করার তিনটি উপায় রয়েছে: একটি সম্পূর্ণ আপডেট, একটি আংশিক আপডেট এবং, একটি সংগ্রহ উইজেটের ক্ষেত্রে, একটি ডেটা রিফ্রেশ। প্রতিটির আলাদা আলাদা কম্পিউটেশনাল খরচ এবং রেমিফিকেশন আছে।

নিম্নলিখিত প্রতিটি আপডেটের ধরন বর্ণনা করে এবং প্রতিটির জন্য কোড স্নিপেট প্রদান করে।

  • সম্পূর্ণ আপডেট: উইজেটটি সম্পূর্ণরূপে আপডেট করতে AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews) এ কল করুন। এটি পূর্বে প্রদত্ত RemoteViews একটি নতুন RemoteViews দিয়ে প্রতিস্থাপন করে। এটি সবচেয়ে গণনামূলকভাবে ব্যয়বহুল আপডেট।

    কোটলিন

    val appWidgetManager = AppWidgetManager.getInstance(context)
    val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also {
    setTextViewText(R.id.textview_widget_layout1, "Updated text1")
    setTextViewText(R.id.textview_widget_layout2, "Updated text2")
    }
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    

    জাভা

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
    remoteViews.setTextViewText(R.id.textview_widget_layout1, "Updated text1");
    remoteViews.setTextViewText(R.id.textview_widget_layout2, "Updated text2");
    appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    
  • আংশিক আপডেট: উইজেটের কিছু অংশ আপডেট করতে AppWidgetManager.partiallyUpdateAppWidget এ কল করুন। এটি পূর্বে প্রদত্ত RemoteViews সাথে নতুন RemoteViews মার্জ করে। updateAppWidget(int[], RemoteViews) এর মাধ্যমে একটি উইজেট অন্তত একটি সম্পূর্ণ আপডেট না পেলে এই পদ্ধতিটি উপেক্ষা করা হয়।

    কোটলিন

    val appWidgetManager = AppWidgetManager.getInstance(context)
    val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also {
    setTextViewText(R.id.textview_widget_layout, "Updated text")
    }
    appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
    

    জাভা

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
    remoteViews.setTextViewText(R.id.textview_widget_layout, "Updated text");
    appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews);
    
  • সংগ্রহের ডেটা রিফ্রেশ: আপনার উইজেটে একটি সংগ্রহ দৃশ্যের ডেটা অবৈধ করতে AppWidgetManager.notifyAppWidgetViewDataChanged কল করুন। এটি RemoteViewsFactory.onDataSetChanged ট্রিগার করে। অন্তর্বর্তী সময়ে, পুরানো ডেটা উইজেটে প্রদর্শিত হয়। আপনি এই পদ্ধতির সাথে সিঙ্ক্রোনাসভাবে ব্যয়বহুল কাজগুলি নিরাপদে সম্পাদন করতে পারেন।

    কোটলিন

    val appWidgetManager = AppWidgetManager.getInstance(context)
    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
    
    

    জাভা

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);
    

আপনি আপনার অ্যাপের যেকোনো জায়গা থেকে এই পদ্ধতিগুলি কল করতে পারেন, যতক্ষণ না অ্যাপটিতে সংশ্লিষ্ট AppWidgetProvider ক্লাসের মতো একই UID থাকে।

কত ঘন ঘন একটি উইজেট আপডেট করতে হবে তা নির্ধারণ করুন

updatePeriodMillis অ্যাট্রিবিউটের জন্য প্রদত্ত মানের উপর নির্ভর করে উইজেটগুলি পর্যায়ক্রমে আপডেট করা হয়। উইজেটটি ব্যবহারকারীর ইন্টারঅ্যাকশন, ব্রডকাস্ট আপডেট বা উভয়ের প্রতিক্রিয়ায় আপডেট হতে পারে।

পর্যায়ক্রমে আপডেট করুন

আপনি appwidget-provider XML-এ AppWidgetProviderInfo.updatePeriodMillis জন্য একটি মান নির্দিষ্ট করে পর্যায়ক্রমিক আপডেটের ফ্রিকোয়েন্সি নিয়ন্ত্রণ করতে পারেন। প্রতিটি আপডেট AppWidgetProvider.onUpdate() পদ্ধতিকে ট্রিগার করে, যেখানে আপনি উইজেট আপডেট করতে কোড রাখতে পারেন। যাইহোক, যদি আপনার উইজেটকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা লোড করতে হয় বা আপডেট হতে 10 সেকেন্ডের বেশি সময় লাগে তাহলে নিম্নলিখিত বিভাগে বর্ণিত ব্রডকাস্ট রিসিভার আপডেটের বিকল্পগুলি বিবেচনা করুন, কারণ 10 সেকেন্ডের পরে, সিস্টেমটি একটি BroadcastReceiver কে অ-প্রতিক্রিয়াশীল বলে মনে করে৷

updatePeriodMillis 30 মিনিটের কম মান সমর্থন করে না। যাইহোক, আপনি যদি পর্যায়ক্রমিক আপডেটগুলি নিষ্ক্রিয় করতে চান তবে আপনি 0 উল্লেখ করতে পারেন।

আপনি ব্যবহারকারীদের একটি কনফিগারেশনে আপডেটের ফ্রিকোয়েন্সি সামঞ্জস্য করতে দিতে পারেন। উদাহরণস্বরূপ, তারা প্রতি 15 মিনিটে বা দিনে মাত্র চারবার একটি স্টক টিকার আপডেট করতে চাইতে পারে। এই ক্ষেত্রে, updatePeriodMillis 0 এ সেট করুন এবং এর পরিবর্তে WorkManager ব্যবহার করুন।

ব্যবহারকারীর ইন্টারঅ্যাকশনের প্রতিক্রিয়ায় আপডেট করুন

ব্যবহারকারীর ইন্টারঅ্যাকশনের উপর ভিত্তি করে উইজেট আপডেট করার জন্য এখানে কিছু প্রস্তাবিত উপায় রয়েছে:

  • অ্যাপের একটি কার্যকলাপ থেকে: ব্যবহারকারীর আলাপচারিতার প্রতিক্রিয়া হিসাবে সরাসরি AppWidgetManager.updateAppWidget এ কল করুন, যেমন ব্যবহারকারীর ট্যাপ৷

  • দূরবর্তী মিথস্ক্রিয়া থেকে, যেমন একটি বিজ্ঞপ্তি বা একটি অ্যাপ উইজেট: একটি PendingIntent তৈরি করুন, তারপরে আমন্ত্রিত Activity , Broadcast বা Service থেকে উইজেট আপডেট করুন৷ আপনি আপনার নিজের অগ্রাধিকার চয়ন করতে পারেন. উদাহরণস্বরূপ, যদি আপনি PendingIntent এর জন্য একটি Broadcast নির্বাচন করেন, তাহলে আপনি BroadcastReceiver অগ্রাধিকার দিতে একটি অগ্রভাগের সম্প্রচার বেছে নিতে পারেন।

একটি সম্প্রচার ইভেন্টের প্রতিক্রিয়ায় আপডেট করুন

একটি ব্রডকাস্ট ইভেন্টের একটি উদাহরণ যার আপডেট করার জন্য একটি উইজেটের প্রয়োজন হয় যখন ব্যবহারকারী একটি ছবি তোলে। এই ক্ষেত্রে, একটি নতুন ফটো সনাক্ত করা হলে আপনি উইজেট আপডেট করতে চান৷

আপনি JobScheduler সাথে একটি কাজের সময় নির্ধারণ করতে পারেন এবং JobInfo.Builder.addTriggerContentUri পদ্ধতি ব্যবহার করে ট্রিগার হিসাবে একটি সম্প্রচার নির্দিষ্ট করতে পারেন৷

আপনি সম্প্রচারের জন্য একটি BroadcastReceiver নিবন্ধন করতে পারেন—উদাহরণস্বরূপ, ACTION_LOCALE_CHANGED জন্য শোনা। যাইহোক, যেহেতু এটি ডিভাইসের সংস্থানগুলি ব্যবহার করে, এটি যত্ন সহকারে ব্যবহার করুন এবং শুধুমাত্র নির্দিষ্ট সম্প্রচার শুনুন। Android 7.0 (API স্তর 24) এবং Android 8.0 (API স্তর 26) এ সম্প্রচারের সীমাবদ্ধতা প্রবর্তনের সাথে, কিছু ব্যতিক্রম ছাড়া অ্যাপগুলি তাদের ম্যানিফেস্টে অন্তর্নিহিত সম্প্রচার নিবন্ধন করতে পারে না।

একটি BroadcastReceiver থেকে একটি উইজেট আপডেট করার সময় বিবেচনা

যদি উইজেটটি AppWidgetProvider সহ BroadcastReceiver থেকে আপডেট করা হয়, তাহলে একটি উইজেট আপডেটের সময়কাল এবং অগ্রাধিকার সম্পর্কিত নিম্নলিখিত বিবেচনার বিষয়ে সচেতন থাকুন।

আপডেটের সময়কাল

একটি নিয়ম হিসাবে, সিস্টেমটি ব্রডকাস্ট রিসিভারগুলিকে, যা সাধারণত অ্যাপের মূল থ্রেডে চলে, 10 সেকেন্ড পর্যন্ত চালানোর অনুমতি দেয় তাদের অ-প্রতিক্রিয়াশীল বিবেচনা করার আগে এবং একটি অ্যাপ্লিকেশন নট রেসপন্ডিং (ANR) ত্রুটি ট্রিগার করে৷ উইজেট আপডেট করতে বেশি সময় লাগলে, নিম্নলিখিত বিকল্পগুলি বিবেচনা করুন:

  • WorkManager ব্যবহার করে একটি টাস্ক শিডিউল করুন।

  • goAsync পদ্ধতিতে রিসিভারকে আরও সময় দিন। এটি রিসিভারদের 30 সেকেন্ডের জন্য কার্যকর করতে দেয়।

আরও তথ্যের জন্য নিরাপত্তা বিবেচনা এবং সর্বোত্তম অনুশীলন দেখুন।

আপডেটের অগ্রাধিকার

ডিফল্টরূপে, AppWidgetProvider.onUpdate ব্যবহার করে তৈরি ব্রডকাস্টগুলি—ব্যাকগ্রাউন্ড প্রসেস হিসাবে চালানো হয়। এর মানে ওভারলোডেড সিস্টেম রিসোর্স ব্রডকাস্ট রিসিভারের আহ্বানে বিলম্ব ঘটাতে পারে। সম্প্রচারকে অগ্রাধিকার দিতে, এটিকে একটি অগ্রভাগ প্রক্রিয়া করুন।

উদাহরণস্বরূপ, যখন ব্যবহারকারী উইজেটের একটি নির্দিষ্ট অংশে ট্যাপ করে তখন PendingIntent.getBroadcast এ পাস করা Intent Intent.FLAG_RECEIVER_FOREGROUND পতাকা যোগ করুন।

ডায়নামিক আইটেমগুলি অন্তর্ভুক্ত করে সঠিক প্রিভিউ তৈরি করুন

চিত্র 1: একটি উইজেট প্রিভিউ যাতে কোনো তালিকা আইটেম নেই।

এই বিভাগটি একটি সংগ্রহ দৃশ্য সহ একটি উইজেটের জন্য একটি উইজেট প্রিভিউতে একাধিক আইটেম প্রদর্শনের জন্য প্রস্তাবিত পদ্ধতির ব্যাখ্যা করে—অর্থাৎ, একটি উইজেট যা একটি ListView , GridView , বা StackView ব্যবহার করে।

যদি আপনার উইজেট এই ভিউগুলির মধ্যে একটি ব্যবহার করে, তাহলে সরাসরি প্রকৃত উইজেট লেআউট প্রদান করে একটি মাপযোগ্য প্রিভিউ তৈরি করা অভিজ্ঞতাকে হ্রাস করে যখন উইজেট প্রিভিউ কোনো আইটেম প্রদর্শন করে না। এটি ঘটে কারণ সংগ্রহ দৃশ্য ডেটা রানটাইমে গতিশীলভাবে সেট করা হয় এবং এটি চিত্র 1 এ দেখানো চিত্রের মতো দেখায়।

সংগ্রহ দৃশ্য সহ উইজেটগুলির পূর্বরূপগুলি উইজেট পিকারে সঠিকভাবে প্রদর্শন করতে, আমরা শুধুমাত্র পূর্বরূপের জন্য মনোনীত একটি পৃথক বিন্যাস ফাইল বজায় রাখার পরামর্শ দিই। এই পৃথক লেআউট ফাইলটিতে প্রকৃত উইজেট লেআউট এবং জাল আইটেম সহ একটি স্থানধারক সংগ্রহের দৃশ্য অন্তর্ভুক্ত রয়েছে। উদাহরণস্বরূপ, আপনি বেশ কয়েকটি জাল তালিকা আইটেম সহ একটি স্থানধারক LinearLayout প্রদান করে একটি ListView অনুকরণ করতে পারেন।

একটি ListView এর জন্য একটি উদাহরণ ব্যাখ্যা করতে, একটি পৃথক লেআউট ফাইল দিয়ে শুরু করুন:

// res/layout/widget_preview.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@drawable/widget_background"
   android:orientation="vertical">

    // Include the actual widget layout that contains ListView.
    <include
        layout="@layout/widget_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    // The number of fake items you include depends on the values you provide
    // for minHeight or targetCellHeight in the AppWidgetProviderInfo
    // definition.

    <TextView android:text="@string/fake_item1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

    <TextView android:text="@string/fake_item2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

</LinearLayout>

AppWidgetProviderInfo মেটাডেটার previewLayout বৈশিষ্ট্য প্রদান করার সময় পূর্বরূপ বিন্যাস ফাইলটি নির্দিষ্ট করুন। আপনি এখনও initialLayout বৈশিষ্ট্যের জন্য প্রকৃত উইজেট বিন্যাস নির্দিষ্ট করেন এবং রানটাইমে RemoteViews তৈরি করার সময় প্রকৃত উইজেট বিন্যাসটি ব্যবহার করেন।

<appwidget-provider
    previewLayout="@layout/widget_previe"
    initialLayout="@layout/widget_view" />

জটিল তালিকা আইটেম

পূর্ববর্তী বিভাগে উদাহরণ জাল তালিকা আইটেম প্রদান করে, কারণ তালিকা আইটেমগুলি TextView অবজেক্ট। আইটেমগুলি জটিল বিন্যাস হলে জাল আইটেম সরবরাহ করা আরও জটিল হতে পারে।

একটি তালিকা আইটেম বিবেচনা করুন যা widget_list_item.xml এ সংজ্ঞায়িত করা হয়েছে এবং দুটি TextView অবজেক্ট নিয়ে গঠিত:

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <TextView android:id="@id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_title" />

    <TextView android:id="@id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_content" />
</LinearLayout>

জাল তালিকা আইটেম প্রদান করতে, আপনি একাধিকবার লেআউট অন্তর্ভুক্ত করতে পারেন, কিন্তু এটি প্রতিটি তালিকা আইটেমকে অভিন্ন করে তোলে। অনন্য তালিকা আইটেম প্রদান করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. পাঠ্য মানগুলির জন্য বৈশিষ্ট্যগুলির একটি সেট তৈরি করুন:

    <resources>
        <attr name="widgetTitle" format="string" />
        <attr name="widgetContent" format="string" />
    </resources>
    
  2. পাঠ্য সেট করতে এই বৈশিষ্ট্যগুলি ব্যবহার করুন:

    <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
        <TextView android:id="@id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetTitle" />
    
        <TextView android:id="@id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetContent" />
    </LinearLayout>
    
  3. পূর্বরূপের জন্য প্রয়োজনীয় যতগুলি শৈলী তৈরি করুন৷ প্রতিটি শৈলীতে মান পুনরায় সংজ্ঞায়িত করুন:

    <resources>
    
        <style name="Theme.Widget.ListItem">
            <item name="widgetTitle"></item>
            <item name="widgetContent"></item>
        </style>
        <style name="Theme.Widget.ListItem.Preview1">
            <item name="widgetTitle">Fake Title 1</item>
            <item name="widgetContent">Fake content 1</item>
        </style>
        <style name="Theme.Widget.ListItem.Preview2">
            <item name="widgetTitle">Fake title 2</item>
            <item name="widgetContent">Fake content 2</item>
        </style>
    
    </resources>
    
  4. পূর্বরূপ বিন্যাসে জাল আইটেমগুলিতে শৈলী প্রয়োগ করুন:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" ...>
    
        <include layout="@layout/widget_view" ... />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview1" />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview2" />
    
    </LinearLayout>