টিএল; ডিআর আপনার navigate
কলগুলি try-catch
(সরল উপায়ে) দিয়ে মুড়িয়ে রাখুন , বা নিশ্চিত করুন যে কেবলমাত্র একটি কল আসবেnavigate
স্বল্প সময়ের মধ্যে । এই সমস্যা সম্ভবত দূরে যাবে না। আপনার অ্যাপে আরও বড় কোড স্নিপেট অনুলিপি করুন এবং চেষ্টা করুন।
হ্যালো. উপরের কয়েকটি দরকারী প্রতিক্রিয়ার ভিত্তিতে, আমি আমার সমাধানটি ভাগ করতে চাই যা বাড়ানো যেতে পারে।
আমার অ্যাপ্লিকেশনটিতে এই ক্র্যাশটির কারণ কোডটি এখানে রয়েছে:
@Override
public void onListItemClicked(ListItem item) {
Bundle bundle = new Bundle();
bundle.putParcelable(SomeFragment.LIST_KEY, item);
Navigation.findNavController(recyclerView).navigate(R.id.action_listFragment_to_listItemInfoFragment, bundle);
}
বাগটি সহজেই উপস্থাপনের একটি উপায় হ'ল আইটেমের তালিকায় একাধিক আঙুল দিয়ে ট্যাপ করা যেখানে প্রতিটি আইটেম ক্লিক করে নতুন স্ক্রিনে নেভিগেশনে সমাধান হয় (মূলত লোকেরা উল্লিখিত একই - খুব অল্প সময়ের মধ্যে দু'একটি ক্লিক ক্লিক করে) )। আমি লক্ষ্য করেছি যে:
- প্রথম অনুরোধ
navigate
সর্বদা সূক্ষ্ম কাজ করে;
navigate
পদ্ধতির দ্বিতীয় এবং সমস্ত অনুরোধগুলি সমাধান করে IllegalArgumentException
।
আমার দৃষ্টিকোণ থেকে, এই পরিস্থিতি খুব প্রায়ই প্রদর্শিত হতে পারে। যেহেতু কোডটির পুনরাবৃত্তিটি একটি খারাপ অভ্যাস এবং পরবর্তী সমাধান সম্পর্কে আমি ভেবেছিলাম এমন একটি পয়েন্টের প্রভাব থাকা ভাল:
public class NavigationHandler {
public static void navigate(View view, @IdRes int destination) {
navigate(view, destination, /* args */null);
}
/**
* Performs a navigation to given destination using {@link androidx.navigation.NavController}
* found via {@param view}. Catches {@link IllegalArgumentException} that may occur due to
* multiple invocations of {@link androidx.navigation.NavController#navigate} in short period of time.
* The navigation must work as intended.
*
* @param view the view to search from
* @param destination destination id
* @param args arguments to pass to the destination
*/
public static void navigate(View view, @IdRes int destination, @Nullable Bundle args) {
try {
Navigation.findNavController(view).navigate(destination, args);
} catch (IllegalArgumentException e) {
Log.e(NavigationHandler.class.getSimpleName(), "Multiple navigation attempts handled.");
}
}
}
এবং এইভাবে উপরের কোডটি কেবল একটি লাইনে পরিবর্তিত হয়:
Navigation.findNavController(recyclerView).navigate(R.id.action_listFragment_to_listItemInfoFragment, bundle);
এটি:
NavigationHandler.navigate(recyclerView, R.id.action_listFragment_to_listItemInfoFragment, bundle);
এমনকি এটি খানিকটা খাটো হয়ে যায়। কোডটি ঠিক যেখানে ঠিক জায়গায় ক্র্যাশ হয়েছিল সেখানে পরীক্ষা করা হয়েছিল। এটি আর অভিজ্ঞতা হয় নি, এবং একই ন্যাভিগেশনগুলির জন্য একই সমাধানটি আরও একই ভুল এড়াতে ব্যবহার করবে।
কোন চিন্তা স্বাগত!
ঠিক কী কারণে দুর্ঘটনা ঘটে
মনে রাখবেন যে আমরা যখন পদ্ধতি ব্যবহার করি তখন আমরা একই ন্যাভিগেশন গ্রাফ, নেভিগেশন কন্ট্রোলার এবং ব্যাক-স্ট্যাকের সাথে কাজ করি Navigation.findNavController
।
আমরা এখানে সর্বদা একই নিয়ামক এবং গ্রাফ পাই। যখন navigate(R.id.my_next_destination)
গ্রাফ বলা হয় এবং ব্যাক-স্ট্যাক প্রায় তত্ক্ষণাত্ পরিবর্তন হয় যখন ইউআই এখনও আপডেট হয় না। শুধু পর্যাপ্ত দ্রুত নয়, তবে এটি ঠিক আছে। ব্যাক-স্ট্যাক পরিবর্তনের পরে নেভিগেশন সিস্টেমটি দ্বিতীয় navigate(R.id.my_next_destination)
কলটি গ্রহণ করে । যেহেতু ব্যাক-স্ট্যাক পরিবর্তিত হয়েছে আমরা এখন স্ট্যাকের শীর্ষ খণ্ডের তুলনায় অপারেটিং করি। শীর্ষ খণ্ডটি হ'ল খণ্ডটি যা আপনি ব্যবহার করে নেভিগেট R.id.my_next_destination
করেন তবে এটিতে আইডি সহ পরবর্তী কোনও গন্তব্য থাকে না R.id.my_next_destination
। সুতরাং আপনি আইডিটির IllegalArgumentException
কারণে পান যে খণ্ডটি সম্পর্কে কিছুই জানে না।
এই সঠিক ত্রুটি NavController.java
পদ্ধতিতে পাওয়া যাবে findDestination
।