কোড পরিদর্শন সরঞ্জাম, যেমন lint ব্যবহার করে, সমস্যা খুঁজে বের করতে এবং আপনার কোড উন্নত করতে সাহায্য করতে পারে, কিন্তু পরিদর্শন সরঞ্জামগুলি কেবল অনেক কিছু অনুমান করতে পারে। উদাহরণস্বরূপ, অ্যান্ড্রয়েড রিসোর্স আইডিগুলি স্ট্রিং, গ্রাফিক্স, রঙ এবং অন্যান্য রিসোর্সের ধরণ সনাক্ত করতে একটি int ব্যবহার করে, তাই পরিদর্শন সরঞ্জামগুলি বলতে পারে না যে আপনি কখন একটি স্ট্রিং রিসোর্স নির্দিষ্ট করেছেন যেখানে আপনার রঙ নির্দিষ্ট করা উচিত ছিল। এই পরিস্থিতির অর্থ হল আপনার অ্যাপটি ভুলভাবে রেন্ডার হতে পারে বা একেবারেই চলতে ব্যর্থ হতে পারে, এমনকি আপনি কোড পরিদর্শন ব্যবহার করলেও।
অ্যানোটেশনগুলি আপনাকে কোড পরিদর্শন সরঞ্জামগুলিতে ইঙ্গিত প্রদান করতে দেয়, যেমন লিন্ট, এই আরও সূক্ষ্ম কোড সমস্যাগুলি সনাক্ত করতে সহায়তা করে। অ্যানোটেশনগুলি মেটাডেটা ট্যাগ হিসাবে যুক্ত করা হয় যা আপনি ভেরিয়েবল, প্যারামিটার এবং রিটার্ন মানের সাথে সংযুক্ত করেন যাতে পদ্ধতি রিটার্ন মান, পাস করা প্যারামিটার, স্থানীয় ভেরিয়েবল এবং ক্ষেত্রগুলি পরিদর্শন করা যায়। কোড পরিদর্শন সরঞ্জামগুলির সাথে ব্যবহার করা হলে, অ্যানোটেশনগুলি আপনাকে নাল পয়েন্টার ব্যতিক্রম এবং রিসোর্স টাইপ দ্বন্দ্বের মতো সমস্যাগুলি সনাক্ত করতে সহায়তা করতে পারে।
অ্যান্ড্রয়েড জেটপ্যাক অ্যানোটেশন লাইব্রেরির মাধ্যমে বিভিন্ন ধরণের অ্যানোটেশন সমর্থন করে। আপনি androidx.annotation প্যাকেজের মাধ্যমে লাইব্রেরি অ্যাক্সেস করতে পারেন।
দ্রষ্টব্য: যদি কোন মডিউলের একটি অ্যানোটেশন প্রসেসরের উপর নির্ভরতা থাকে, তাহলে সেই নির্ভরতা যোগ করার জন্য আপনাকে Kotlin-এর জন্য kapt অথবা ksp নির্ভরতা কনফিগারেশন অথবা Java-এর জন্য annotationProcessor নির্ভরতা কনফিগারেশন ব্যবহার করতে হবে।
আপনার প্রকল্পে টীকা যোগ করুন
আপনার প্রোজেক্টে টীকা সক্রিয় করতে, আপনার লাইব্রেরি বা অ্যাপে androidx.annotation:annotation নির্ভরতা যোগ করুন। আপনি যখন কোনও কোড পরিদর্শন বা lint টাস্ক চালান তখন আপনার যোগ করা যেকোনো টীকা পরীক্ষা করা হয়।
জেটপ্যাক অ্যানোটেশন লাইব্রেরি নির্ভরতা যোগ করুন
জেটপ্যাক অ্যানোটেশন লাইব্রেরিটি গুগলের ম্যাভেন রিপোজিটরিতে প্রকাশিত। আপনার প্রকল্পে জেটপ্যাক অ্যানোটেশন লাইব্রেরি যুক্ত করতে, আপনার build.gradle অথবা build.gradle.kts ফাইলের dependencies ব্লকে নিম্নলিখিত লাইনটি অন্তর্ভুক্ত করুন:
কোটলিন
dependencies { implementation("androidx.annotation:annotation:1.9.1") }
খাঁজকাটা
dependencies { implementation 'androidx.annotation:annotation:1.9.1' }
যদি আপনি আপনার নিজস্ব লাইব্রেরি মডিউলে অ্যানোটেশন ব্যবহার করেন, তাহলে অ্যানোটেশনগুলি annotations.zip ফাইলে XML ফর্ম্যাটে Android Archive (AAR) আর্টিফ্যাক্টের অংশ হিসেবে অন্তর্ভুক্ত করা হবে। androidx.annotation নির্ভরতা যোগ করলে আপনার লাইব্রেরির কোনও ডাউনস্ট্রিম ব্যবহারকারীর জন্য নির্ভরতা তৈরি হয় না।
দ্রষ্টব্য: যদি আপনি অন্যান্য জেটপ্যাক লাইব্রেরি ব্যবহার করেন, তাহলে আপনার androidx.annotation নির্ভরতা যোগ করার প্রয়োজন নাও হতে পারে। যেহেতু অন্যান্য অনেক জেটপ্যাক লাইব্রেরি অ্যানোটেশন লাইব্রেরির উপর নির্ভর করে, তাই আপনার ইতিমধ্যেই অ্যানোটেশনগুলিতে অ্যাক্সেস থাকতে পারে।
জেটপ্যাক রিপোজিটরিতে অন্তর্ভুক্ত টীকাগুলির সম্পূর্ণ তালিকার জন্য, হয় জেটপ্যাক অ্যানোটেশন লাইব্রেরি রেফারেন্স দেখুন অথবা import androidx.annotation. স্টেটমেন্টের জন্য উপলব্ধ বিকল্পগুলি প্রদর্শন করতে অটোকম্পলিট বৈশিষ্ট্যটি ব্যবহার করুন।
কোড পরিদর্শন চালান
অ্যান্ড্রয়েড স্টুডিও থেকে কোড পরিদর্শন শুরু করতে, যার মধ্যে অ্যানোটেশন যাচাইকরণ এবং স্বয়ংক্রিয় লিন্ট চেকিং অন্তর্ভুক্ত রয়েছে, মেনু থেকে বিশ্লেষণ > কোড পরিদর্শন করুন নির্বাচন করুন। অ্যান্ড্রয়েড স্টুডিও সম্ভাব্য সমস্যাগুলিকে চিহ্নিত করতে এবং সম্ভাব্য সমাধানের পরামর্শ দেওয়ার জন্য দ্বন্দ্ব বার্তা প্রদর্শন করে।
কমান্ড লাইন ব্যবহার করে lint টাস্কটি চালিয়ে আপনি অ্যানোটেশনগুলিও জোরদার করতে পারেন। যদিও এটি একটি ক্রমাগত ইন্টিগ্রেশন সার্ভারের সমস্যাগুলি চিহ্নিত করার জন্য কার্যকর হতে পারে, lint টাস্কটি নালনেস অ্যানোটেশনগুলি জোরদার করে না (পরবর্তী বিভাগে বর্ণিত); শুধুমাত্র অ্যান্ড্রয়েড স্টুডিও এটি করে। লিন্ট পরিদর্শনগুলি সক্ষম এবং চালানোর বিষয়ে আরও তথ্যের জন্য, লিন্ট চেকগুলির মাধ্যমে আপনার কোড উন্নত করা দেখুন।
যদিও টীকা দ্বন্দ্ব সতর্কতা তৈরি করে, এই সতর্কতাগুলি আপনার অ্যাপকে কম্পাইল করা থেকে বিরত রাখে না।
শূন্যতা টীকা
জাভা কোডে নালনেস অ্যানোটেশন কার্যকর হতে পারে যাতে মানগুলি নাল হতে পারে কিনা তা কার্যকর করা যায়। কোটলিন কোডে এগুলি কম কার্যকর, কারণ কোটলিনে নাল্যাবিলিটি নিয়ম তৈরি করা হয়েছে যা কম্পাইলের সময় প্রয়োগ করা হয়। একটি প্রদত্ত চলক, প্যারামিটার, অথবা রিটার্ন মানের শূন্যতা পরীক্ষা করতে @Nullable এবং @NonNull টীকা যোগ করুন। @Nullable টীকাটি এমন একটি চলক, প্যারামিটার, অথবা রিটার্ন মান নির্দেশ করে যা শূন্য হতে পারে। @NonNull এমন একটি চলক, প্যারামিটার, অথবা রিটার্ন মান নির্দেশ করে যা শূন্য হতে পারে না।
উদাহরণস্বরূপ, যদি একটি স্থানীয় চলক যার মধ্যে একটি নাল মান রয়েছে তাকে একটি পদ্ধতিতে প্যারামিটার হিসেবে পাস করা হয় যেখানে @NonNull অ্যানোটেশনটি সেই প্যারামিটারের সাথে সংযুক্ত থাকে, তাহলে কোড তৈরি করলে একটি সতর্কতা তৈরি হয় যা একটি নন-নাল সংঘাত নির্দেশ করে। এছাড়াও, ফলাফলটি নাল কিনা তা পরীক্ষা না করে @Nullable দ্বারা চিহ্নিত একটি পদ্ধতির ফলাফল উল্লেখ করার চেষ্টা করলে একটি নালনেস সতর্কতা তৈরি হয়। শুধুমাত্র তখনই একটি পদ্ধতির রিটার্ন মানে @Nullable ব্যবহার করুন যদি পদ্ধতির প্রতিটি ব্যবহার স্পষ্টভাবে নাল-চেক করা থাকে।
নিচের উদাহরণটি কার্যক্ষমতার ক্ষেত্রে nullability প্রদর্শন করে। Kotlin উদাহরণ কোড @NonNull অ্যানোটেশন ব্যবহার করে না কারণ এটি স্বয়ংক্রিয়ভাবে জেনারেট করা বাইটকোডে যোগ করা হয় যখন একটি নন-nullable টাইপ নির্দিষ্ট করা হয়। জাভা উদাহরণটি @NonNull অ্যানোটেশন ব্যবহার করে context এবং attrs প্যারামিটার পরীক্ষা করে পরীক্ষা করে যে পাস করা প্যারামিটার মানগুলি null নয়। এটি আরও পরীক্ষা করে যে onCreateView() পদ্ধতি নিজেই null ফেরত দেয় না:
কোটলিন
... /** Annotation not used because of the safe-call operator(?)**/ override fun onCreateView( name: String?, context: Context, attrs: AttributeSet ): View? { ... } ...
জাভা
import androidx.annotation.NonNull; ... /** Add support for inflating the <fragment> tag. **/ @NonNull @Override public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) { ... } ...
শূন্যতা বিশ্লেষণ
অ্যান্ড্রয়েড স্টুডিও আপনার কোডে স্বয়ংক্রিয়ভাবে নালনেস অ্যানোটেশন অনুমান এবং সন্নিবেশ করার জন্য একটি নাল্যাবিলিটি বিশ্লেষণ চালানো সমর্থন করে। একটি নাল্যাবিলিটি বিশ্লেষণ আপনার কোডের সমস্ত পদ্ধতির শ্রেণিবিন্যাস জুড়ে চুক্তিগুলি স্ক্যান করে সনাক্ত করে:
- কলিং পদ্ধতি যা null রিটার্ন করতে পারে।
- যেসব পদ্ধতিতে null রিটার্ন করা উচিত নয়।
- ভেরিয়েবল, যেমন ক্ষেত্র, স্থানীয় ভেরিয়েবল এবং প্যারামিটার, যা শূন্য হতে পারে।
- ভেরিয়েবল, যেমন ফিল্ড, স্থানীয় ভেরিয়েবল এবং প্যারামিটার, যেগুলোর মান শূন্য হতে পারে না।
বিশ্লেষণটি তখন স্বয়ংক্রিয়ভাবে সনাক্ত করা অবস্থানগুলিতে উপযুক্ত নাল টীকাগুলি সন্নিবেশ করায়।
অ্যান্ড্রয়েড স্টুডিওতে একটি nullability বিশ্লেষণ চালানোর জন্য, Analyze > Infer Nullity নির্বাচন করুন। অ্যান্ড্রয়েড স্টুডিও আপনার কোডে সনাক্ত করা অবস্থানগুলিতে অ্যান্ড্রয়েড @Nullable এবং @NonNull অ্যানোটেশনগুলি সন্নিবেশ করায়। একটি null বিশ্লেষণ চালানোর পরে, ইনজেক্ট করা অ্যানোটেশনগুলি যাচাই করা একটি ভাল অনুশীলন।
দ্রষ্টব্য: nullness অ্যানোটেশন যোগ করার সময়, অটোকম্পলিট অ্যান্ড্রয়েড null অ্যানোটেশনের পরিবর্তে IntelliJ @Nullable এবং @NotNull অ্যানোটেশনের পরামর্শ দিতে পারে এবং সংশ্লিষ্ট লাইব্রেরিটি স্বয়ংক্রিয়ভাবে আমদানি করতে পারে। তবে, অ্যান্ড্রয়েড স্টুডিও লিন্ট চেকার শুধুমাত্র অ্যান্ড্রয়েড null অ্যানোটেশনের সন্ধান করে। আপনার অ্যানোটেশন যাচাই করার সময়, নিশ্চিত করুন যে আপনার প্রকল্পটি অ্যান্ড্রয়েড null অ্যানোটেশন ব্যবহার করে যাতে লিন্ট চেকার কোড পরিদর্শনের সময় আপনাকে সঠিকভাবে অবহিত করতে পারে।
রিসোর্স টীকা
রিসোর্সের ধরণ যাচাই করা কার্যকর হতে পারে কারণ অ্যান্ড্রয়েড রিসোর্সের রেফারেন্স, যেমন ড্রয়েবল এবং স্ট্রিং রিসোর্স, পূর্ণসংখ্যা হিসেবে পাস করা হয়।
যে কোডটি একটি প্যারামিটারকে একটি নির্দিষ্ট ধরণের রিসোর্স, যেমন একটি String , রেফারেন্স করার আশা করে, তা প্রত্যাশিত রেফারেন্স টাইপ int তে পাস করা যেতে পারে, কিন্তু আসলে একটি ভিন্ন ধরণের রিসোর্স, যেমন একটি R.string রিসোর্স, রেফারেন্স করে।
উদাহরণস্বরূপ, @StringRes অ্যানোটেশন যোগ করে দেখুন যে কোনও রিসোর্স প্যারামিটারে R.string রেফারেন্স আছে কিনা, যেমনটি এখানে দেখানো হয়েছে:
কোটলিন
abstract fun setTitle(@StringRes resId: Int)
জাভা
public abstract void setTitle(@StringRes int resId)
কোড পরিদর্শনের সময়, যদি প্যারামিটারে R.string রেফারেন্স পাস না করা হয় তবে অ্যানোটেশনটি একটি সতর্কতা তৈরি করে।
অন্যান্য রিসোর্স ধরণের জন্য টীকা, যেমন @DrawableRes , @DimenRes , @ColorRes , এবং @InterpolatorRes , একই টীকা বিন্যাস ব্যবহার করে যোগ করা যেতে পারে এবং কোড পরিদর্শনের সময় চালানো যেতে পারে।
যদি আপনার প্যারামিটার একাধিক রিসোর্স টাইপ সমর্থন করে, তাহলে আপনি একটি নির্দিষ্ট প্যারামিটারে একাধিক রিসোর্স টাইপ অ্যানোটেশন রাখতে পারেন। @AnyRes ব্যবহার করে বোঝান যে অ্যানোটেটেড প্যারামিটারটি যেকোনো ধরনের R রিসোর্স হতে পারে।
যদিও আপনি @ColorRes ব্যবহার করে নির্দিষ্ট করতে পারেন যে একটি প্যারামিটার একটি রঙের রিসোর্স হওয়া উচিত, একটি রঙের পূর্ণসংখ্যা ( RRGGBB বা AARRGGBB ফর্ম্যাটে) একটি রঙের রিসোর্স হিসাবে স্বীকৃত নয়। পরিবর্তে, @ColorInt অ্যানোটেশন ব্যবহার করে নির্দেশ করুন যে একটি প্যারামিটার অবশ্যই একটি রঙের পূর্ণসংখ্যা হতে হবে। বিল্ড টুলগুলি ভুল কোডকে ফ্ল্যাগ করবে যা একটি রঙের পূর্ণসংখ্যার পরিবর্তে android.R.color.black এর মতো একটি রঙের রিসোর্স আইডি অ্যানোটেটেড পদ্ধতিতে পাস করে।
থ্রেড টীকা
থ্রেড অ্যানোটেশনগুলি পরীক্ষা করে যে কোনও পদ্ধতি নির্দিষ্ট ধরণের থ্রেড থেকে ডাকা হয়েছে কিনা। নিম্নলিখিত থ্রেড অ্যানোটেশনগুলি সমর্থিত:
বিল্ড টুলগুলি @MainThread এবং @UiThread অ্যানোটেশনগুলিকে বিনিময়যোগ্য হিসাবে বিবেচনা করে, তাই আপনি @MainThread পদ্ধতি থেকে @UiThread পদ্ধতিগুলিকে কল করতে পারেন এবং তদ্বিপরীতভাবেও। তবে, বিভিন্ন থ্রেডে একাধিক ভিউ সহ সিস্টেম অ্যাপের ক্ষেত্রে, একটি UI থ্রেড মূল থ্রেড থেকে আলাদা হতে পারে। অতএব, আপনার @UiThread এর সাথে একটি অ্যাপের ভিউ হায়ারার্কির সাথে সম্পর্কিত পদ্ধতিগুলি টীকা করা উচিত এবং @MainThread এর সাথে একটি অ্যাপের জীবনচক্রের সাথে সম্পর্কিত পদ্ধতিগুলি টীকা করা উচিত।
যদি একটি ক্লাসের সমস্ত পদ্ধতির থ্রেডিং প্রয়োজনীয়তা একই হয়, তাহলে আপনি ক্লাসে একটি একক থ্রেড অ্যানোটেশন যোগ করতে পারেন যাতে যাচাই করা যায় যে ক্লাসের সমস্ত পদ্ধতি একই ধরণের থ্রেড থেকে ডাকা হয়েছে।
থ্রেড অ্যানোটেশনের একটি সাধারণ ব্যবহার হল যাচাই করা যে @WorkerThread দিয়ে টীকা করা পদ্ধতি বা ক্লাসগুলি শুধুমাত্র একটি উপযুক্ত ব্যাকগ্রাউন্ড থ্রেড থেকে ডাকা হয়।
মান সীমাবদ্ধতা টীকা
পাস করা প্যারামিটারের মান যাচাই করতে @IntRange , @FloatRange , এবং @Size অ্যানোটেশন ব্যবহার করুন। ব্যবহারকারীরা রেঞ্জ ভুল করার সম্ভাবনা থাকা প্যারামিটারগুলিতে প্রয়োগ করার সময় @IntRange এবং @FloatRange উভয়ই সবচেয়ে কার্যকর।
@IntRange অ্যানোটেশন যাচাই করে যে একটি পূর্ণসংখ্যা বা দীর্ঘ প্যারামিটার মান একটি নির্দিষ্ট পরিসরের মধ্যে রয়েছে। নিম্নলিখিত উদাহরণটি নির্দেশ করে যে alpha প্যারামিটারে 0 থেকে 255 পর্যন্ত একটি পূর্ণসংখ্যা মান থাকতে হবে:
কোটলিন
fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
জাভা
public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }
@FloatRange অ্যানোটেশন পরীক্ষা করে যে একটি float অথবা double প্যারামিটার মান একটি নির্দিষ্ট ফ্লোটিং পয়েন্ট মানের মধ্যে আছে কিনা। নিম্নলিখিত উদাহরণটি নির্দেশ করে যে alpha প্যারামিটারে 0.0 থেকে 1.0 পর্যন্ত একটি float মান থাকতে হবে:
কোটলিন
fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
জাভা
public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
@Size অ্যানোটেশন একটি সংগ্রহ বা অ্যারের আকার বা একটি স্ট্রিংয়ের দৈর্ঘ্য পরীক্ষা করে। @Size অ্যানোটেশনটি নিম্নলিখিত গুণাবলী যাচাই করতে ব্যবহার করা যেতে পারে:
- সর্বনিম্ন আকার, যেমন
@Size(min=2) - সর্বোচ্চ আকার, যেমন
@Size(max=2) - সঠিক আকার, যেমন
@Size(2) - এমন একটি সংখ্যা যার আকার অবশ্যই গুণিতক হতে হবে, যেমন
@Size(multiple=2)
উদাহরণস্বরূপ, @Size(min=1) একটি সংগ্রহ খালি আছে কিনা তা পরীক্ষা করে, এবং @Size(3) যাচাই করে যে একটি অ্যারেতে ঠিক তিনটি মান রয়েছে।
নিম্নলিখিত উদাহরণটি নির্দেশ করে যে location অ্যারেতে কমপক্ষে একটি উপাদান থাকতে হবে:
কোটলিন
fun getLocation(button: View, @Size(min=1) location: IntArray) { button.getLocationOnScreen(location) }
জাভা
void getLocation(View button, @Size(min=1) int[] location) { button.getLocationOnScreen(location); }
অনুমতি টীকা
@RequiresPermission অ্যানোটেশন ব্যবহার করে কোনও পদ্ধতির কলারের অনুমতি যাচাই করুন। বৈধ অনুমতির তালিকা থেকে একটি একক অনুমতি পরীক্ষা করতে, anyOf অ্যাট্রিবিউট ব্যবহার করুন। অনুমতির সেট পরীক্ষা করতে, allOf অ্যাট্রিবিউট ব্যবহার করুন। নিম্নলিখিত উদাহরণটি setWallpaper() পদ্ধতিটি টীকা করে নির্দেশ করে যে পদ্ধতির কলারের অবশ্যই permission.SET_WALLPAPERS অনুমতি থাকতে হবে:
কোটলিন
@RequiresPermission(Manifest.permission.SET_WALLPAPER) @Throws(IOException::class) abstract fun setWallpaper(bitmap: Bitmap)
জাভা
@RequiresPermission(Manifest.permission.SET_WALLPAPER) public abstract void setWallpaper(Bitmap bitmap) throws IOException;
নিম্নলিখিত উদাহরণে copyImageFile() পদ্ধতির কলারকে বহিরাগত স্টোরেজের পঠন অ্যাক্সেস এবং অনুলিপি করা ছবিতে অবস্থান মেটাডেটা পড়ার অ্যাক্সেস উভয়ই থাকতে হবে:
কোটলিন
@RequiresPermission(allOf = [ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION ]) fun copyImageFile(dest: String, source: String) { ... }
জাভা
@RequiresPermission(allOf = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION}) public static final void copyImageFile(String dest, String source) { //... }
ইন্টেন্টের অনুমতির জন্য, স্ট্রিং ফিল্ডে অনুমতির প্রয়োজনীয়তা লিখুন যা ইন্টেন্ট অ্যাকশনের নাম সংজ্ঞায়িত করে:
কোটলিন
@RequiresPermission(android.Manifest.permission.BLUETOOTH) const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
জাভা
@RequiresPermission(android.Manifest.permission.BLUETOOTH) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
যেসব কন্টেন্ট প্রোভাইডারদের পঠন এবং লেখার অ্যাক্সেসের জন্য আলাদা অনুমতির প্রয়োজন, তাদের জন্য প্রতিটি অনুমতির প্রয়োজনীয়তা @RequiresPermission.Read অথবা @RequiresPermission.Write অ্যানোটেশনে মুড়ে দিন:
কোটলিন
@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS)) val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
জাভা
@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS)) public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
পরোক্ষ অনুমতি
যখন কোনও অনুমতি কোনও পদ্ধতির প্যারামিটারে সরবরাহ করা নির্দিষ্ট মানের উপর নির্ভর করে, তখন নির্দিষ্ট অনুমতিগুলি তালিকাভুক্ত না করে প্যারামিটারে @RequiresPermission ব্যবহার করুন। উদাহরণস্বরূপ, startActivity(Intent) পদ্ধতিটি পদ্ধতিতে প্রেরিত অভিপ্রায়ের উপর একটি পরোক্ষ অনুমতি ব্যবহার করে:
কোটলিন
abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
জাভা
public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)
যখন আপনি পরোক্ষ অনুমতি ব্যবহার করেন, তখন বিল্ড টুলগুলি ডেটা ফ্লো বিশ্লেষণ করে পরীক্ষা করে যে পদ্ধতিতে পাস করা আর্গুমেন্টে কোনও @RequiresPermission অ্যানোটেশন আছে কিনা। তারপর তারা পদ্ধতিতে প্যারামিটার থেকে বিদ্যমান কোনও অ্যানোটেশন প্রয়োগ করে। startActivity(Intent) উদাহরণে, Intent ক্লাসের অ্যানোটেশনগুলি startActivity(Intent) এর অবৈধ ব্যবহারের উপর ফলস্বরূপ সতর্কতা প্রদান করে যখন উপযুক্ত অনুমতি ছাড়াই একটি ইন্টেন্ট পদ্ধতিতে পাস করা হয়, যেমন চিত্র 1-এ দেখানো হয়েছে।

চিত্র ১. startActivity(Intent) পদ্ধতিতে একটি পরোক্ষ অনুমতি টীকা থেকে তৈরি সতর্কতা।
বিল্ড টুলগুলি Intent ক্লাসে সংশ্লিষ্ট intent action নামের উপর টীকা থেকে startActivity(Intent) এ সতর্কতা তৈরি করে:
কোটলিন
@RequiresPermission(Manifest.permission.CALL_PHONE) const val ACTION_CALL = "android.intent.action.CALL"
জাভা
@RequiresPermission(Manifest.permission.CALL_PHONE) public static final String ACTION_CALL = "android.intent.action.CALL";
প্রয়োজনে, আপনি কোনও পদ্ধতির প্যারামিটার টীকা করার সময় @RequiresPermission.Read অথবা @RequiresPermission.Write এর পরিবর্তে @RequiresPermission ব্যবহার করতে পারেন। তবে, পরোক্ষ অনুমতির জন্য @RequiresPermission পঠন বা লেখার অনুমতি টীকাগুলির সাথে একত্রে ব্যবহার করা উচিত নয়।
রিটার্ন মান টীকা
@CheckResult অ্যানোটেশন ব্যবহার করে যাচাই করুন যে কোনও পদ্ধতির ফলাফল বা রিটার্ন মান আসলে ব্যবহৃত হচ্ছে। @CheckResult দিয়ে প্রতিটি অকার্যকর পদ্ধতিতে টীকা দেওয়ার পরিবর্তে, সম্ভাব্য বিভ্রান্তিকর পদ্ধতির ফলাফল স্পষ্ট করার জন্য টীকাটি যোগ করুন।
উদাহরণস্বরূপ, নতুন জাভা ডেভেলপাররা প্রায়শই ভুল করে ভাবেন যে < String >.trim() মূল স্ট্রিং থেকে হোয়াইটস্পেস সরিয়ে দেয়। @CheckResult ফ্ল্যাগ দিয়ে পদ্ধতিটি টীকা করার সময় < String >.trim() ব্যবহার করা হয় যেখানে কলার পদ্ধতির রিটার্ন মান নিয়ে কিছুই করে না।
নিচের উদাহরণটি checkPermissions() পদ্ধতিটি টীকা করে পরীক্ষা করে যে পদ্ধতির রিটার্ন মান আসলে রেফারেন্স করা হয়েছে কিনা। এটি enforcePermission() পদ্ধতিটিকে একটি পদ্ধতি হিসেবেও নামকরণ করে যা ডেভেলপারকে প্রতিস্থাপন হিসেবে প্রস্তাব করা হবে:
কোটলিন
@CheckResult(suggest = "#enforcePermission(String,int,int,String)") abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
জাভা
@CheckResult(suggest="#enforcePermission(String,int,int,String)") public abstract int checkPermission(@NonNull String permission, int pid, int uid);
কলসুপার টীকা
@CallSuper অ্যানোটেশন ব্যবহার করে যাচাই করুন যে একটি ওভাররাইডিং পদ্ধতি পদ্ধতির সুপার বাস্তবায়নকে কল করে।
নিচের উদাহরণটি onCreate() পদ্ধতিটি টীকা করে যাতে নিশ্চিত করা যায় যে যেকোনো ওভাররাইডিং পদ্ধতি বাস্তবায়ন super.onCreate() কল করে:
কোটলিন
@CallSuper override fun onCreate(savedInstanceState: Bundle?) { }
জাভা
@CallSuper protected void onCreate(Bundle savedInstanceState) { }
টাইপডেফ টীকা
টাইপডেফ অ্যানোটেশনগুলি পরীক্ষা করে যে কোনও নির্দিষ্ট প্যারামিটার, রিটার্ন মান, বা ক্ষেত্র কোনও নির্দিষ্ট ধ্রুবকের সেটকে উল্লেখ করে কিনা। তারা কোড সমাপ্তিকে স্বয়ংক্রিয়ভাবে অনুমোদিত ধ্রুবকগুলি অফার করতে সক্ষম করে।
অন্যান্য ধরণের কোড রেফারেন্স যাচাই করার জন্য পূর্ণসংখ্যা এবং স্ট্রিং সেটের গণনাকৃত অ্যানোটেশন তৈরি করতে @IntDef এবং @StringDef অ্যানোটেশন ব্যবহার করুন।
Typedef অ্যানোটেশনগুলি @interface ব্যবহার করে নতুন এনুমেরেটেড অ্যানোটেশন টাইপ ঘোষণা করে। @IntDef এবং @StringDef অ্যানোটেশনগুলি, @Retention সহ, নতুন অ্যানোটেশনটি অ্যানোট করে এবং এনুমেরেটেড টাইপ সংজ্ঞায়িত করার জন্য প্রয়োজনীয়। @Retention(RetentionPolicy.SOURCE) অ্যানোটেশন কম্পাইলারকে .class ফাইলে এনুমেরেটেড অ্যানোটেশন ডেটা সংরক্ষণ না করার নির্দেশ দেয়।
নিম্নলিখিত উদাহরণে একটি অ্যানোটেশন তৈরির ধাপগুলি দেখানো হয়েছে যা পরীক্ষা করে যে একটি পদ্ধতি প্যারামিটার হিসাবে পাস করা মান সংজ্ঞায়িত ধ্রুবকগুলির একটিকে উল্লেখ করে কিনা:
কোটলিন
import androidx.annotation.IntDef //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(AnnotationRetention.SOURCE) @IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS) annotation class NavigationMode // Declare the constants. const val NAVIGATION_MODE_STANDARD = 0 const val NAVIGATION_MODE_LIST = 1 const val NAVIGATION_MODE_TABS = 2 abstract class ActionBar { // Decorate the target methods with the annotation. // Attach the annotation. @get:NavigationMode @setparam:NavigationMode abstract var navigationMode: Int }
জাভা
import androidx.annotation.IntDef; //... public abstract class ActionBar { //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(RetentionPolicy.SOURCE) @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) public @interface NavigationMode {} // Declare the constants. public static final int NAVIGATION_MODE_STANDARD = 0; public static final int NAVIGATION_MODE_LIST = 1; public static final int NAVIGATION_MODE_TABS = 2; // Decorate the target methods with the annotation. @NavigationMode public abstract int getNavigationMode(); // Attach the annotation. public abstract void setNavigationMode(@NavigationMode int mode); }
যখন আপনি এই কোডটি তৈরি করেন, তখন একটি সতর্কতা তৈরি হয় যদি mode প্যারামিটারটি সংজ্ঞায়িত ধ্রুবকগুলির একটি ( NAVIGATION_MODE_STANDARD , NAVIGATION_MODE_LIST , অথবা NAVIGATION_MODE_TABS ) উল্লেখ না করে।
@IntDef এবং @IntRange একত্রিত করে বোঝান যে একটি পূর্ণসংখ্যা হয় একটি নির্দিষ্ট ধ্রুবকের সেট অথবা একটি পরিসরের মধ্যে একটি মান হতে পারে।
ফ্ল্যাগের সাথে ধ্রুবকের সমন্বয় সক্ষম করুন
যদি ব্যবহারকারীরা অনুমোদিত ধ্রুবকগুলিকে একটি পতাকার সাথে একত্রিত করতে পারেন (যেমন | , & , ^ , ইত্যাদি), তাহলে আপনি একটি flag বৈশিষ্ট্য সহ একটি টীকা সংজ্ঞায়িত করতে পারেন যাতে একটি প্যারামিটার বা রিটার্ন মান একটি বৈধ প্যাটার্নের উল্লেখ করে কিনা তা পরীক্ষা করা যায়।
নিম্নলিখিত উদাহরণটি বৈধ DISPLAY_ ধ্রুবকের একটি তালিকা সহ DisplayOptions অ্যানোটেশন তৈরি করে:
কোটলিন
import androidx.annotation.IntDef ... @IntDef(flag = true, value = [ DISPLAY_USE_LOGO, DISPLAY_SHOW_HOME, DISPLAY_HOME_AS_UP, DISPLAY_SHOW_TITLE, DISPLAY_SHOW_CUSTOM ]) @Retention(AnnotationRetention.SOURCE) annotation class DisplayOptions ...
জাভা
import androidx.annotation.IntDef; ... @IntDef(flag=true, value={ DISPLAY_USE_LOGO, DISPLAY_SHOW_HOME, DISPLAY_HOME_AS_UP, DISPLAY_SHOW_TITLE, DISPLAY_SHOW_CUSTOM }) @Retention(RetentionPolicy.SOURCE) public @interface DisplayOptions {} ...
যখন আপনি একটি অ্যানোটেশন ফ্ল্যাগ দিয়ে কোড তৈরি করেন, তখন যদি সজ্জিত প্যারামিটার বা রিটার্ন মান একটি বৈধ প্যাটার্ন উল্লেখ না করে তবে একটি সতর্কতা তৈরি হয়।
টীকা রাখুন
@Keep অ্যানোটেশন নিশ্চিত করে যে বিল্ড টাইমে কোডটি মিনিফাই করার সময় কোনও অ্যানোটেটেড ক্লাস বা পদ্ধতি সরানো না হয়। এই অ্যানোটেশনটি সাধারণত এমন পদ্ধতি এবং ক্লাসগুলিতে যোগ করা হয় যা প্রতিফলনের মাধ্যমে অ্যাক্সেস করা হয় যাতে কম্পাইলার কোডটিকে অব্যবহৃত হিসাবে বিবেচনা না করে।
সতর্কতা: @Keep ব্যবহার করে আপনি যে ক্লাস এবং পদ্ধতিগুলি টীকা করেন সেগুলি সর্বদা আপনার অ্যাপের APK-তে প্রদর্শিত হয়, এমনকি যদি আপনি কখনও আপনার অ্যাপের লজিকের মধ্যে এই ক্লাস এবং পদ্ধতিগুলি উল্লেখ না করেন।
আপনার অ্যাপের আকার ছোট রাখতে, আপনার অ্যাপে প্রতিটি @Keep অ্যানোটেশন সংরক্ষণ করা প্রয়োজন কিনা তা বিবেচনা করুন। যদি আপনি একটি অ্যানোটেটেড ক্লাস বা পদ্ধতি অ্যাক্সেস করার জন্য প্রতিফলন ব্যবহার করেন, তাহলে আপনার ProGuard নিয়মে একটি -if শর্তসাপেক্ষ ব্যবহার করুন, যেখানে প্রতিফলন কলকারী ক্লাসটি নির্দিষ্ট করা থাকবে।
আপনার কোড কীভাবে ছোট করবেন এবং কোন কোডটি সরানো হবে না তা নির্দিষ্ট করার বিষয়ে আরও তথ্যের জন্য, আপনার অ্যাপটি সঙ্কুচিত করুন, অস্পষ্ট করুন এবং অপ্টিমাইজ করুন দেখুন।
কোড দৃশ্যমানতা টীকা
কোডের নির্দিষ্ট অংশ, যেমন পদ্ধতি, ক্লাস, ক্ষেত্র বা প্যাকেজের দৃশ্যমানতা বোঝাতে নিম্নলিখিত টীকাগুলি ব্যবহার করুন।
পরীক্ষার জন্য কোড দৃশ্যমান করুন
@VisibleForTesting অ্যানোটেশনটি নির্দেশ করে যে একটি অ্যানোটেটেড পদ্ধতিটি পরীক্ষাযোগ্য করার জন্য স্বাভাবিকের চেয়ে বেশি দৃশ্যমান। এই অ্যানোটেশনটিতে একটি ঐচ্ছিক otherwise আর্গুমেন্ট রয়েছে যা আপনাকে পরীক্ষার জন্য দৃশ্যমান করার প্রয়োজন না হলে পদ্ধতিটির দৃশ্যমানতা কী হবে তা নির্ধারণ করতে দেয়। লিন্ট উদ্দেশ্যযুক্ত দৃশ্যমানতা জোরদার করার জন্য otherwise আর্গুমেন্ট ব্যবহার করে।
নিম্নলিখিত উদাহরণে, myMethod() সাধারণত private হয়, কিন্তু পরীক্ষার জন্য এটি package-private । VisibleForTesting.PRIVATE উপাধির সাহায্যে, যদি এই পদ্ধতিটি private অ্যাক্সেস দ্বারা অনুমোদিত প্রসঙ্গের বাইরে থেকে ডাকা হয়, যেমন একটি ভিন্ন সংকলন ইউনিট থেকে, তাহলে lint একটি বার্তা প্রদর্শন করে।
কোটলিন
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun myMethod() { ... }
জাভা
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) void myMethod() { ... }
আপনি @VisibleForTesting(otherwise = VisibleForTesting.NONE) নির্দিষ্ট করেও বলতে পারেন যে কোনও পদ্ধতি কেবল পরীক্ষার জন্য বিদ্যমান। এই ফর্মটি @RestrictTo(TESTS) ব্যবহারের মতোই। তারা উভয়ই একই লিন্ট চেক করে।
একটি API সীমাবদ্ধ করুন
@RestrictTo অ্যানোটেশনটি নির্দেশ করে যে অ্যানোটেটেড API (প্যাকেজ, ক্লাস, বা পদ্ধতি) তে অ্যাক্সেস সীমিত, নিম্নরূপ:
উপশ্রেণী
শুধুমাত্র সাবক্লাসে API অ্যাক্সেস সীমাবদ্ধ করতে @RestrictTo(RestrictTo.Scope.SUBCLASSES) অ্যানোটেশন ফর্ম ব্যবহার করুন।
শুধুমাত্র অ্যানোটেটেড ক্লাসকে প্রসারিত করে এমন ক্লাসগুলিই এই API অ্যাক্সেস করতে পারবে। জাভা protected মডিফায়ার যথেষ্ট সীমাবদ্ধ নয়, কারণ এটি একই প্যাকেজের মধ্যে সম্পর্কহীন ক্লাস থেকে অ্যাক্সেসের অনুমতি দেয়। এছাড়াও, এমন কিছু ক্ষেত্রে আছে যখন আপনি ভবিষ্যতের নমনীয়তার জন্য একটি পদ্ধতি public রাখতে চান, কারণ আপনি কখনই পূর্বে protected এবং ওভাররাইড করা পদ্ধতি public করতে পারবেন না, তবে আপনি একটি ইঙ্গিত দিতে চান যে ক্লাসটি ক্লাসের মধ্যে বা শুধুমাত্র সাবক্লাস থেকে ব্যবহারের জন্য তৈরি।
লাইব্রেরি
শুধুমাত্র আপনার লাইব্রেরিতে API অ্যাক্সেস সীমাবদ্ধ করতে @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) অ্যানোটেশন ফর্মটি ব্যবহার করুন।
শুধুমাত্র আপনার লাইব্রেরি কোডই অ্যানোটেটেড API অ্যাক্সেস করতে পারবে। এটি আপনাকে আপনার কোডকে আপনার পছন্দের প্যাকেজ হায়ারার্কিতে সংগঠিত করতে দেয় না বরং সম্পর্কিত লাইব্রেরির একটি গ্রুপের মধ্যে কোডটি ভাগ করতে দেয়। এই বিকল্পটি ইতিমধ্যেই জেটপ্যাক লাইব্রেরিগুলিতে উপলব্ধ যেখানে প্রচুর বাস্তবায়ন কোড রয়েছে যা বহিরাগত ব্যবহারের জন্য নয়, তবে বিভিন্ন পরিপূরক জেটপ্যাক লাইব্রেরিগুলিতে ভাগ করার জন্য এটি public হতে হবে।
পরীক্ষামূলক
অন্যান্য ডেভেলপারদের আপনার টেস্টিং API গুলি অ্যাক্সেস করতে বাধা দিতে @RestrictTo(RestrictTo.Scope.TESTS) অ্যানোটেশন ফর্মটি ব্যবহার করুন।
শুধুমাত্র টেস্টিং কোডই অ্যানোটেটেড API অ্যাক্সেস করতে পারে। এটি অন্যান্য ডেভেলপারদের এমন API ব্যবহার করতে বাধা দেয় যা আপনি শুধুমাত্র পরীক্ষার উদ্দেশ্যে ডেভেলপমেন্ট করতে চান।