অ্যানড্রয়েড ফ্রেগমেন্ট অনাটাচ () অবমূল্যায়িত


326

আমি সর্বশেষ সমর্থন লাইব্রেরি (সংস্করণ ২৩.০.০) ব্যবহার করতে আমার অ্যাপ্লিকেশনটি আপডেট করেছি, আমি জানতে পেরেছি যে তারা খণ্ড শ্রেণীর অনাটাচ () ফাংশনটি অবমূল্যায়ন করেছে।

পরিবর্তে:

onAttach (Activity activity)

এটি বরফ:

onAttach (Context context)

যেহেতু আমার অ্যাপ্লিকেশনটি হ্রাসের আগে পাস করা ক্রিয়াকলাপটি ব্যবহার করে, আমার মনে হয় একটি সম্ভাব্য সমাধান:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}

এটি কি সঠিক উপায় হবে?

হালনাগাদ:

যদি আমি 23 টিরও কম এপিআই দিয়ে কোনও ডিভাইস চালনা করি তবে নতুন অনটাক () এমনকি কল করা হবে না। আমি আশা করি তারা এটাই করল না!

আপডেট 2:

এসডিকে সর্বশেষ আপডেট সহ সমস্যা সমাধান করা হয়েছে।

আমি আমার এপিআই 22 ডিভাইসে পরীক্ষা করেছি এবং অনাটাচ (প্রসঙ্গ) কল করা হচ্ছে।

কয়েক সপ্তাহ আগে আমি খুলে থাকা বাগের প্রতিবেদন এবং গুগলের লোকদের কাছ থেকে দেওয়া উত্তরগুলি অনুসরণ করতে এখানে ক্লিক করুন


আপনি যদি নিজের পাস হওয়া উদাহরণ থেকে নির্দিষ্ট ক্রিয়াকলাপের পদ্ধতিগুলি ব্যবহার করছেন তবে আপনি কি আপনার কার্যকলাপের প্রসঙ্গে প্রসঙ্গটি দেওয়ার চেষ্টা করেছেন? ক্রিয়াকলাপ মনে রাখবেন প্রসঙ্গের একটি সাবক্লাস। সম্ভবত একটি castালাই কাজ করবে।
মার্কস্কেফ

কোনও কারণে, অ্যানট্যাচ () বলা হচ্ছে না! কোন ধারনা? আপনি কি সর্বশেষ সমর্থন lib আপডেট করার চেষ্টা করেছেন?
তারেক খুরি

2
এপিআই কেন সরানো হয়েছে Context? Activityযাইহোক কোনও খণ্ড সংযুক্ত এবং প্রদর্শন করার জন্য আপনার কি দরকার নেই ? আর কীভাবে আপনি Contextপ্যারামিটার ব্যবহার করবেন ?
কেনি ওয়ার্ডেন

1
আমি এটি একটি বাগ হিসাবে পোস্ট করেছি, লিঙ্ক কোড. google.com/p/android/issues/detail?id=183358 দেখুন
তারেক খুরি

6
নতুনটি কল করার জন্য onAttach(Context context), আপনাকে হয় এমন একটি ডিভাইস ব্যবহার করতে হবে যার কমপক্ষে এপিআই 23 রয়েছে বা অ্যান্ড্রয়েড.সুপুর্ট.ভি 4.app.ফ্রেগমেন্ট ব্যবহার করা উচিত। এখানে
nevzo

উত্তর:


337

ক্রিয়াকলাপ একটি প্রসঙ্গ হয় তাই আপনি যদি প্রসঙ্গটি কেবল কার্যকলাপের চেক করতে পারেন এবং প্রয়োজনে এটি কাস্ট করেন।

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity a;

    if (context instanceof Activity){
        a=(Activity) context;
    }

}

আপডেট: কেউ কেউ দাবি করছেন যে নতুন Contextওভাররাইডটি কখনই ডাকা হয় না। আমি কিছু পরীক্ষা করেছি এবং এমন দৃশ্য খুঁজে পাচ্ছি না যেখানে এটি সত্য এবং উত্স কোড অনুসারে এটি কখনই সত্য হওয়া উচিত নয়। সব ক্ষেত্রে আমি পরীক্ষিত, উভয় পূর্ব ও পরবর্তী SDK23, উভয় Activityএবং Contextএর সংস্করণ onAttachবলা হয়। যদি আপনি এমন কোনও পরিস্থিতি খুঁজে পান যেখানে এটি না হয় তবে আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি একটি সমস্যার নমুনা প্রকল্প তৈরি করুন এবং এটি অ্যান্ড্রয়েড দলে রিপোর্ট করুন

আপডেট 2: বাগগুলি দ্রুত স্থির হয়ে যাওয়ার কারণে আমি কেবলমাত্র অ্যান্ড্রয়েড সমর্থন লাইব্রেরি টুকরো ব্যবহার করি। উপরের বিষয়টি মনে হচ্ছে যেখানে ওভাররাইডগুলি সঠিকভাবে ডাকা হয় না কেবলমাত্র যদি আপনি কাঠামোর খণ্ডগুলি ব্যবহার করেন তবে তা প্রকাশ পায়।


5
প্রসঙ্গ সহ অনাচাচকে আসলেই কোনও সমাধান নয় কারণ ক্রিয়াকলাপের সাথে অ্যাটাকের মতোই বলা হয় না। আপনার যদি প্যারামিটার হিসাবে কোনও ক্রিয়াকলাপের সাথে অ্যাটাচে কিছু সূচনা কোড থাকে তবে এই পরিবর্তনটি কাজ করবে না।
বাডি

2
না, এটি একই রকম কাজ করে না, অন্তত আমার ক্ষেত্রে। আমি অনাচারে কার্যকলাপ বা প্রসঙ্গ ব্যবহার করি না, আমি আরম্ভ করি। আমি অ্যাটচ-এর পরিবর্তে ক্রিয়াকলাপের সাথে ক্রিয়াকলাপের সাথে পরিবর্তনের চেষ্টা করেছি এবং এটি একইভাবে কল হয় না। সুতরাং তারা সহজেই বিনিময়যোগ্য হয় না।
বুডি

7
বাডির একই সমস্যাগুলি ... onAttach(Context)বলা হয় বলে মনে হয় না।
স্টাফেন

2
আমি আমার কোডটি দিয়েছি এবং আমি যাচাই না করা সম্ভব কিনা তা যাচাই করতে পারি onAttach(context)
চাদ বিংহাম

2
আমার ক্ষেত্রে, আমরা যদি সিস্টেমের আগে ক্লিয়ার করা ক্রিয়াকলাপটি পুনরায় চালু করি তবে অনটাক () কল হবে না। তবে এটি সবসময় এর মতো হয় না। আমি অনাক্ট (প্রসঙ্গে প্রসঙ্গ), রেফ্যাকটিভিটি = নতুন WeakReferences <> ((অ্যাপকম্প্যাটএকটিভিটি) প্রসঙ্গে) একটি WeakReferences এর একটি সূচনা রেখেছি। এবং এটি মাঝে মাঝে অনক্রিটভিউতে () নলপয়েন্টারএক্সসেপশন ছুড়ে দেয়।
কিমি চিউ

45

এই Google ... প্রস্তাবিত পরিবর্তন থেকে অন্য পরিবর্তন হল: প্রতিস্থাপন onAttach(Activity activity)সঙ্গে onAttach(Context context)যেহেতু পুরোনো API গুলি আমার অ্যাপ্লিকেশান ক্র্যাশ onAttach(Context context)নেটিভ টুকরা আহ্বান করা হবে না।

আমি নেটিভ টুকরা (android.app.Fraament) ব্যবহার করছি তাই পুরানো এপিআইগুলিতে এটি আবার কাজ করার জন্য আমাকে নিম্নলিখিত কাজগুলি করতে হয়েছিল (<23)।

আমি যা করেছি তা এখানে:

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    // Code here
}

@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // Code here
    }
}

মিঃ ইউন হারকিউইট, আপনি কীভাবে এডিআই 23 এর উপরে এটি করবেন তা ব্যাখ্যা করতে পারেন, দয়া করে আমাকে অগ্রিম ধন্যবাদ, ই / অ্যান্ড্রয়েডআরটাইম: ফ্যাটাল এক্সেসপেশন: মূল, জাভা.এলং.ক্লাসকাস্ট এক্সেক্সশন: com.ual.SMS_Activity@afd5683, অ্যান্ড্রয়েডে। android.support.v4.app.FraamentManagerImpl.execSingleAction এ, সমর্থন.v4.app.FraamentManagerImpl.moveToState। এখানে আমি প্রয়োজনীয় লাইন পোস্ট করেছি যা আপনি আমার বাগটি জানতে পারবেন।
মোহনরাজ এস

@ মোহনরাজরাজ এপিআই ২৪ তে এটি একই (আমি যেটি ব্যবহার করেছি) আপনার কোডের টুকরা অনুসারে, আপনার সমস্যাটি এটি দিয়ে কিছু করতে হবে বলে মনে হয় না।
ইওন হারকিউট

@ ইয়ানোহান হারকিউয়েট, আপনার উত্তরের জন্য আপনাকে ধন্যবাদ, আমাকে পরীক্ষা করে আপডেট করতে দিন।
মোহনরাজ এস

1
পুরানো API গুলি টার্গেট করতে অসুবিধার কারণে আপনি এই সম্পর্কে গুগল সম্পর্কে সন্তুষ্ট নন। ঠিক আছে, আপনি যে আশীর্বাদটিকে পুরানো এপিআই এর লক্ষ্য করতে পারেন তা বিবেচনা করুন, যেখানে অ্যাপল উদাহরণস্বরূপ, আপনাকে কেবল পঙ্গু করে দেবে এবং আপনাকে কেবলমাত্র নতুনকে সমর্থন করতে বাধ্য করবে।
স্টান

39

আপনি যদি ফ্রেমওয়ার্ক টুকরো টুকরো টুকরোটি ব্যবহার করেন এবং ডিভাইসের SDK সংস্করণটি 23 এর চেয়ে কম হয়, কল করা OnAttach(Context context)হবে না।

আমি পরিবর্তে সমর্থন টুকরা ব্যবহার করি, তাই অবচয় স্থির হয় এবং onAttach(Context context)সর্বদা কল হয়ে যায়।


11

onAttachখণ্ড কোড থেকে বর্তমানে Contextএটি বর্তমান ক্রিয়াকলাপ: উত্স কোড কিনা তা পরিষ্কার নয়

public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

আপনি যদি একবার getActivityখেয়াল করেন তবে একই কলটি দেখতে পাবেন

/**
 * Return the Activity this fragment is currently associated with.
 */
final public Activity getActivity() {
    return mHost == null ? null : mHost.getActivity();
}

সুতরাং আপনি যদি নিশ্চিত হতে চান যে আপনি ক্রিয়াকলাপটি পাচ্ছেন তবে ব্যবহার করুন getActivity()( onAttachআপনার মধ্যে Fragment) তবে যাচাই করতে ভুলবেন না nullকারণ যদি mHostহয় তবে nullআপনার কার্যকলাপ হবেnull


6
@Override
public void onAttach(Context context) {
    super.onAttach(context);

    Activity activity = context instanceof Activity ? (Activity) context : null;
}

5

যদিও মনে হচ্ছে বেশিরভাগ ক্ষেত্রে এটি যথেষ্ট পরিমাণে রয়েছে onAttach(Context), কিছু ফোন রয়েছে (যেমন: শাওমি রেডমি নোট 2) যেখানে এটি কল করা হচ্ছে না, সুতরাং এটি নলপয়েন্টারএক্সেপশনগুলির কারণ হয়ে দাঁড়ায়। তাই নিরাপদে থাকার জন্য আমি অবমুক্ত পদ্ধতিটি ছাড়ারও পরামর্শ দিই:

// onAttach(Activity) is necessary in some Xiaomi phones
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    _onAttach(activity);
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    _onAttach(context);
}

private void _onAttach(Context context) {
    // do your real stuff here
}

3

এসডিকে পরিচালকের সাথে নতুন সমর্থন লাইব্রেরি ডাউনলোড করুন এবং অন্তর্ভুক্ত করুন

compile 'com.android.support:appcompat-v7:23.1.1'

গ্রেড.এপ এ এবং এপিআই 23 তে সংকলন সংস্করণ সেট করুন


1

নীচের উত্তরটি অ্যান্ড্রয়েড বিকাশকারী ওয়েবসাইটের ফ্রেগমেন্ট টিউটোরিয়ালে সংঘটিত এই অবচয় সতর্কতার সাথে সম্পর্কিত এবং উপরের পোস্টগুলির সাথে সম্পর্কিত নাও হতে পারে।

আমি টিউটোরিয়াল পাঠে এই কোডটি ব্যবহার করেছি এবং এটি কার্যকর হয়েছে।

public void onAttach(Context context){
    super.onAttach(context);

    Activity activity = getActivity();

আমি চিন্তিত ছিলাম যে ডকুমেন্টেশনের বিবরণ অনুযায়ী যা করা যেতে পারে সেই ক্রিয়াকলাপটি বাতিল হতে পারে।

getActivity

ফ্র্যাগমেন্টএটিভিটি গতিঅ্যাকটিভিটি () এই টুকরাটির সাথে বর্তমানে যুক্ত এই বিভাগটি ক্রিয়াকলাপটি প্রদান করুন Return পরিবর্তে যদি খণ্ডটি প্রসঙ্গে যুক্ত হয় তবে তা বাতিল করতে পারে।

তবে মূল_অ্যাক্টিভিটির অনক্রেটটি স্পষ্টভাবে দেখায় যে খণ্ডটি লোড হয়েছিল এবং তাই এই পদ্ধতির পরে, খণ্ডের ক্রিয়াকলাপটি কল করানো মূল_অ্যাক্টিভিটি শ্রেণিতে ফিরে আসবে।

getSupportFragmentManager ()। startTransaction () .এডডি (আর। আইড। ফ্রেমেন্ট_কন্টেইনার, ফার্স্টফ্র্যাগমেন্ট) .কমিট ();

আমি আশা করি এর সাথে আমি ঠিক আছি আমি একেবারে নবাগত।


1

আপনি সম্ভবত ব্যবহার করছেন android.support.v4.app.FragmentonAttachপদ্ধতির পরিবর্তে এর জন্য , কেবল খণ্ডটি যার সাথে যুক্ত getActivity()তা পেতে ব্যবহার করুন FragmentActivity। অন্যথায় আপনি onAttach(Context context)পদ্ধতি ব্যবহার করতে পারে ।


0

এটি আমার পক্ষে কাজ করেছিল যখন আমি ইন্টারফেসের 'টপসেকশনলিস্টনার' এর সংজ্ঞা প্রদান করেছি, এটির অবজেক্ট অ্যাক্টিভিটি কম্যান্ডার:

  //This method gets called whenever we attach fragment to the activity
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Activity a=getActivity();
    try {
        if(context instanceof Activity)
           this.activitycommander=(TopSectionListener)a;
    }catch (ClassCastException e){
        throw new ClassCastException(a.toString());}

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.