একটি খণ্ডে প্রসঙ্গ ব্যবহার করা


664

আমি কীভাবে কোনও খণ্ডে প্রসঙ্গ পেতে পারি?

আমাকে আমার ডাটাবেসটি ব্যবহার করতে হবে যার নির্মাতা প্রসঙ্গে নিচ্ছেন, getApplicationContext()এবং FragmentClass.thisআমি কাজ করতে পারি না তাই কী করতে পারি?

ডাটাবেস নির্মাণকারী

public Database(Context ctx)
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

উত্তর:


1313

আপনি ব্যবহার করতে পারেন getActivity(), যা ক এর সাথে যুক্ত ক্রিয়াকলাপটি ফিরিয়ে দেয় fragment
ক্রিয়াকলাপটি হ'ল একটি context (যেহেতু Activityপ্রসারিত Context)


212
getActivity () যদি সংশ্লিষ্ট খণ্ডটির অনাচারের আগে ডাকা হয় তবে তা নালায় ফিরে আসতে পারে।
arne.jans

4
আমি এই গুগল ব্লগটি মেমরি ফাঁস ... অ্যান্ড্রয়েড-ডেভেলপার্স.ব্লগস্পট . com/2009/01/ … এ পড়ছিলাম । আমি যদি getActivity () পদ্ধতিটি ব্যবহার করি তবে অ্যাপটি কী মেমোরি ফাঁস হওয়ার ঝুঁকিতে থাকবে না? ব্লগটি "প্রসঙ্গ-ক্রিয়াকলাপের পরিবর্তে প্রসঙ্গ-অ্যাপ্লিকেশনটি ব্যবহার করে চেষ্টা করুন" যা getApplicationContext () কেবলমাত্র ক্রিয়াকলাপের জন্য কাজ করে না খণ্ড শ্রেণীর জন্য কাজ করে "।
সাইমন

40
বিচ্ছিন্ন খণ্ডগুলির সমস্যার সমাধান হ'ল খণ্ডটি তৈরি getActivity().getApplicationContext()হওয়ার সময় একটি উদাহরণের পরিবর্তনশীলের মান সংরক্ষণ করা এবং তারপরে যখনই আপনি খণ্ড শ্রেণীর ভিতরে চান তখন সেই প্রসঙ্গটি ব্যবহার করুন। সেই প্রসঙ্গে খণ্ড বিচ্ছিন্নতাগুলি টিকে থাকবে।
পাইভজান

8
অ্যাপ্লিকেশন প্রসঙ্গে ঘুরে দেখার পরিবর্তে, আপনার অ্যাপ্লিকেশন শ্রেণীর অভ্যন্তরে একটি স্থির প্রসঙ্গ তৈরি করুন এবং এটি চালু করুন onCreate (): MyApplication.sContext = getApplicationContext (); তারপরে আপনি বিচ্ছিন্নতার বিষয়ে চিন্তা না করে কোনও ক্রিয়াকলাপ / অংশ থেকে এটিকে অ্যাক্সেস করতে পারেন।
এডুকো

3
@ মিলানিয়েজ: getActivityসর্বদা উপলব্ধ ছিল। এটা getContextযা এপিআই 23 যোগ করা হয়েছিল
mhsmith

130

উপরের উত্তর হিসাবে করতে, আপনি onAttachটুকরা পদ্ধতিটি ওভাররাইড করতে পারেন :

public static class DummySectionFragment extends Fragment{
...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        DBHelper = new DatabaseHelper(activity);
    }
}

3
আমি এটির পরামর্শ দিচ্ছি, কারণ getActivity () নালার ফেরত দেয় যদি অনাটাচকে এখনও না বলা হয়।
arne.jans

9
তবে, মনে রাখবেন, যখন অনাচ () কল করা হয় তখন কোনও দর্শন নেই। সুতরাং আপনি এখনও ভিউ সহ কিছু করতে পারবেন না!
জোর্ডিড

2
@ আইয়ামবক্সের পরিবর্তে যদি DatabaseHelperপ্রয়োজন হয় ? উদাহরণস্বরূপ, একটি ...FragmentActivityActivityAdapter
জাগো

4
আপনি যদি আপনার ক্রিয়াকলাপের জন্য কোনও রেফারেন্স সঞ্চয় করে থাকেন onAttach(Activity activity)তবে আপনার এটি প্রকাশ করা উচিতonDetach()
ভোভोस्স্ট

3
onAttachপদ্ধতি, অবচিত হয়েছেOverrides deprecated method in 'android.support.v4.app.Fragment'
মুহাম্মদ সাকিব

24

সর্বদা ব্যবহার করুন আপনার সংযুক্ত ক্রিয়াকলাপের প্রসঙ্গটি পেতে getActivity () পদ্ধতিটি তবে সর্বদা একটি জিনিস মনে রাখবেন: টুকরোগুলি কিছুটা অস্থির থাকে এবং getActivityকিছু সময় নালায় ফিরে আসে, সুতরাং এর জন্য, প্রাসঙ্গিক হওয়ার আগে সর্বদা আইসএডড () পদ্ধতিটি পরীক্ষা করে দেখুন getActivity()


15
আমি এটি বলব না যে খণ্ডগুলি "সামান্য অস্থির", ভগ্নাংশটি কোনও ক্রিয়াকলাপের সাথে সম্পর্কিত না হলে getActivity () নালাগুলি ফিরে আসা বেশ স্বাভাবিক বলে মনে হয়। এটি ধরে নেওয়া হচ্ছে যে getActivity () "বাতিল করা উচিত নয়" (যা ভুল) যা আপনার অ্যাপ্লিকেশনটিকে (এবং ফ্রেগমেন্ট শ্রেণি নয়) অস্থির করে তুলবে।
personne3000

3
@ personne3000 আমি আরও শুনতে চাই কখন কোনও খণ্ড ক্রিয়াকলাপের সাথে সম্পর্কিত নয়? কখন এটি ঘটছে এবং কেন? GetActivity () ব্যবহার করার জন্য আমাদের কি খণ্ডে isdd () পরীক্ষা করা উচিত? থাম্বের কোনও নিয়ম?
সট্টি

2
@ সট্টি আমি আপনাকে এটির জন্য একটি নতুন প্রশ্ন তৈরি করতে উত্সাহিত করি (বা কোনও বিদ্যমান সন্ধান করুন), কারণ এই নির্দিষ্ট বিষয়টি মূল প্রশ্ন থেকে কিছুটা আলাদা। সাধারণ তথ্যের জন্য আপনার বিকাশকারী.অ্যান্ড্রয়েড .com/ guide/ compferences/ frations.html# লাইফ সাইকেলটি দেখতে পারেন । মূলত, অনআটাচ এর আগে এবং অন ডেটাকের পরে কোনও ক্রিয়াকলাপ নেই। এবং অনতাচ এবং অনঅ্যাক্টিভিটি তৈরির মধ্যে, ক্রিয়াকলাপের অনক্রিট এখনও কল করা হয়নি। GetActivity () ব্যবহার করার সময়, নিশ্চিত হয়ে নিন যে আপনার ক্রিয়াকলাপটি ইতিমধ্যে তৈরি হয়ে গেছে, এবং যদি এটি ধ্বংস হয়ে যায় বা আপনার খণ্ডটি পৃথক হয়ে যায় তবে কী ঘটবে তা ভেবে দেখুন।
personne3000

22

আমি যে খণ্ডটি পেয়েছি তার প্রসঙ্গটি পাওয়ার সহজতম এবং সুনির্দিষ্ট উপায় হ'ল আপনি ViewGroupযখন onCreateViewপদ্ধতিটি কল করেন তখন সরাসরি এটি থেকে পাওয়া আপনি এখানে কমপক্ষে নষ্ট হওয়ার বিষয়ে নিশ্চিত নন getActivity():

public class Animal extends Fragment { 
  Context thiscontext;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    thiscontext = container.getContext();

10
এটাই কনটেইনার প্রসঙ্গে, আমার মনে হয় ... "এই প্রসঙ্গ" নয়।
ফ্যাটি 27'14

2
@ এজি 1 আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন এটি আপনার কোডটি ক্র্যাশ করেছে? এটি এখন পর্যন্ত আমার কাছে সেরা সমাধানটি রয়েছে
মাচাডো

3
আসলে কথোপকথনগুলিতে কনটেইনারটি শূন্য হতে পারে। সাবধান!
লুকাস টেস্ক

এই সমাধানটি অনক্রিট ভিউতে নয়, অনভিউতে তৈরি করা উচিত।
আন্দ্রেয়া ডি সিমোন

13

পূর্বে আমি ব্যবহার করছি onAttach (Activity activity)পেতে contextমধ্যেFragment

সমস্যা

onAttach (Activity activity)পদ্ধতি এপিআই স্তর 23-এ অসমর্থিত হয়েছে।

সমাধান

এখন প্রসঙ্গটি পেতে Fragmentআমরা ব্যবহার করতে পারিonAttach (Context context)

onAttach (Context context)

  • বলা যখন একটি টুকরা প্রথম তার সংযুক্ত contextonCreate(Bundle)এই পরে বলা হবে।

নথিপত্র

/**
 * Called when a fragment is first attached to its context.
 * {@link #onCreate(Bundle)} will be called after this.
 */
@CallSuper
public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

কোডের উদাহরণ

public class FirstFragment extends Fragment {


    private Context mContext;
    public FirstFragment() {
        // Required empty public constructor
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rooView=inflater.inflate(R.layout.fragment_first, container, false);

        Toast.makeText(mContext, "THIS IS SAMPLE TOAST", Toast.LENGTH_SHORT).show();
        // Inflate the layout for this fragment
        return rooView;
    }

}

বিঃদ্রঃ

আমরা প্রবেশ করতেও ব্যবহার getActivity()করতে পারি তবে আপনি যদি বর্তমানে কোনও পিতামাতার সাথে সংযুক্ত না contextথাকেন Fragmentsতবে getActivity()ফিরে আসতে পারি ,nullfragmentactivity



6

inflaterওভাররাইড করার সময় আপনি প্যারামিটার থেকে প্রসঙ্গটিও পেতে পারেন onCreateView

public static class MyFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
        /* ... */
        Context context = inflater.getContext();
        /* ... */
    }
}

5

অন্য বিকল্প পদ্ধতি হ'ল:

আপনি ব্যবহার করে প্রসঙ্গটি পেতে পারেন:

getActivity().getApplicationContext();

5

খণ্ডের অভ্যন্তরে প্রসঙ্গটি পেতে এটি ব্যবহার করে সম্ভব হবে getActivity():

public Database()
{
    this.context = getActivity();
    DBHelper = new DatabaseHelper(this.context);
}
  • সতর্কতা অবলম্বন করুন, Activityব্যবহার করে টুকরাটির সাথে যুক্ত হতে getActivity(), আপনি এটি ব্যবহার করতে পারেন তবে এটি মেমরি ফাঁস হওয়ার কারণ প্রস্তাবিত নয়।

আমি মনে করি পদ্ধতিটি Activityথেকে আরও ভাল আপোচার অবশ্যই পাওয়া উচিত onAttach():

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

ভিউ অ্যাক্টিভিটি কোনও খণ্ডে ব্যবহার করা উচিত নয় যদি না যে দৃশ্যটি যাইহোক কার্যকলাপের অংশ না হয়। আপনি কেন কোনও খণ্ডে কোনও দৃশ্য স্ফূরণ করবেন তবে এর থেকে কিছু উল্লেখ করা যায় না?
tyczj

এই উত্তরটি অন্যরকম কিছু সম্পর্কে, আপনি যে ভিউয়ের উপরে ভিউ সন্ধান করতে চান তার বিষয়ে কথা বলছেন Activity.findViewByIdthat ক্রিয়াকলাপের নিবন্ধিত সামগ্রী দর্শন (এর মধ্য দিয়ে সেট করা setContentView) এর একটি দর্শন অনুসন্ধান করার জন্য কেবল একটি সুবিধা পদ্ধতি । আপনার সঠিক উদাহরণে আপনি কল করছেন View.findViewById, না Activity.findViewByIdএবং সঠিক পদ্ধতিতে আপনি পদ্ধতিটি আহ্বান করছেন । সম্পূর্ণ ভিন্ন সমস্যা এবং স্পষ্টতই আপনি এই দর্শনটি ধারণ করে না এমন দৃশ্যাবলীতে আপনার দৃষ্টিভঙ্গি খুঁজে পেতে সক্ষম হবেন না।
জেএইচএইচ

3

getContext() এপিআই 23 এ এসেছিল it কোডের যে কোনও জায়গায় getActivity () এর সাথে এটি প্রতিস্থাপন করুন।

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


3

যেহেতু এপিআই লেভেল 23 রয়েছে getContext()তবে আপনি যদি পুরানো সংস্করণগুলি সমর্থন করতে চান getActivity().getApplicationContext()তবে আমি এখনও সমর্থন সংস্করণটি ব্যবহার করার প্রস্তাব Fragmentদিই android.support.v4.app.Fragment


2

getActivity() কনটেক্সটের একটি শিশু যাতে এটি আপনার পক্ষে কাজ করা উচিত


2

সমর্থন লাইব্রেরি থেকে টুকরা ব্যবহার করুন -

android.support.v4.app.Fragment

এবং তারপরে ওভাররাইড করুন

void onAttach (Context context) {
  this.context = context;
}

এইভাবে আপনি নিশ্চিত হতে পারেন যে প্রসঙ্গটি সর্বদা একটি নন-মান হবে।


2

আপনার বিভিন্ন বিকল্প রয়েছে:

  • যদি আপনার minSDK <= 21 হয় তবে আপনি এটি ব্যবহার করতে পারেন getActivity(), কারণ এটি একটি aContext
  • আপনার minSDK যদি> = 23 হয় তবে আপনি ব্যবহার করতে পারেন getContext()

আপনার যদি পুরানো সংস্করণগুলি সমর্থন করার প্রয়োজন না হয় তবে সাথে যান getContext()


2

কোটলিনের জন্য আপনি contextসরাসরি টুকরো টুকরো ব্যবহার করতে পারেন । তবে কিছু ক্ষেত্রে আপনি একটি ত্রুটি পাবেন

অমিল টাইপ করুন: অনুমানক প্রকার প্রসঙ্গ? তবে প্রসঙ্গটি প্রত্যাশিত ছিল

তার জন্য আপনি এটি করতে পারেন

val ctx = context ?: return
textViewABC.setTextColor(ContextCompat.getColor(ctx, android.R.color.black))

একটি কোটলিন সংস্করণ উপভোগ করার জন্য ধন্যবাদ, যা ভাল কাজ করে, তবে আমি পিকাসো.জেট () এর সাথে প্রসঙ্গটি পাওয়ার চেষ্টা করছি এবং এটি কখনই কার্যকর হয় না, প্রসঙ্গটি পেতে আমি উপরের নমুনাগুলি থেকে যথাসাধ্য চেষ্টা করেছি। সর্বোপরি আমি এই বার্তাটি পেয়েছি - অনেকগুলি আর্গুমেন্ট পাস হয়েছে ... দয়া করে সহায়তা করুন। ভাল সিটিএক্স = প্রসঙ্গ?: পিকাসো.গেট (সিটিএক্স)। লোড (নির্বাচিতগ্যালারি.আইমেজ ইউআরএল)। স্থানধারক (আর। মিপম্যাপ.িক_লাঞ্চার) .আইনটো (গ্যালারী আইমেজ)
অ্যাডে

@ অ্যাড আপনার খণ্ডে, "ক্রিয়াকলাপ !!" ব্যবহার করার চেষ্টা করুন "সিটিএক্স" এর পরিবর্তে এবং আমাকে জানান এটি সাহায্য করে বা না
কিশান সোলঙ্কি

@ কিশানসোলানকি 124। দ্রুত প্রতিক্রিয়া জন্য অনেক ধন্যবাদ। আমি একই পরামর্শ সহ আপনার পরামর্শটি চেষ্টা করেছিলাম - এখনও কাজ করছি না। সঠিক ত্রুটি প্রম্পটটি হ'ল - প্রকাশ্য মজাদার মজাদার জন্য প্রচুর যুক্তি (): পিকাসো !. এই বার্তাটি আমাকে ভাবতে বাধ্য করে, সম্ভবত অন্য কিছু হতে পারে? খুশি হলেও, প্রসঙ্গ না পেয়ে পিকাসো ব্যবহার করে আমার কাজটি চালিয়ে যাওয়ার একটি উপায় খুঁজে পেয়েছেন। আবার ধন্যবাদ.
এডি



1

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

তারপরে: আপনি নিজের ইচ্ছামতো ক্রিয়াকলাপ, প্রসঙ্গ বা অ্যাপ্লিকেশন কনটেক্সট পেতে খণ্ডটিকে ডিগ্রি করতে পারেন:

this.getActivity()ক্রিয়াকলাপটি this.getContext()আপনাকে হ্যান্ডেল this.getActivity().getApplicationContext()দেবে আপনাকে প্রসঙ্গে একটি হ্যান্ডেল দেবে যা আপনাকে অ্যাপ্লিকেশন প্রসঙ্গে হ্যান্ডেল দেবে। অ্যাপ্লিকেশন প্রসঙ্গটি ডিবিতে পৌঁছে দেওয়ার সময় আপনার অবশ্যই ব্যবহার করা উচিত।


1

সহজ উপায়টি ব্যবহার করা getActivity()। তবে আমি মনে করি এটি ব্যবহারের বড় বিভ্রান্তিgetActivity() এখানে প্রসঙ্গটি পেতে পদ্ধতিটি একটি নাল পয়েন্টার ব্যতিক্রম।

এর জন্য প্রথমে isAdded()পদ্ধতিটি পরীক্ষা করে দেখুন যা এটি যুক্ত হয়েছে কিনা তা নির্ধারণ করবে এবং তারপরে আমরা getActivity()ক্রিয়াকলাপের প্রসঙ্গটি পেতে ব্যবহার করতে পারি ।



1

আপনি কল করতে পারেন getActivity()বা,

public void onAttach(Context context) {
    super.onAttach(context);
    this.activity = (CashActivity) context;
    this.money = this.activity.money;
}

1

আপনি প্রসঙ্গ পেতে getActivity () পদ্ধতি ব্যবহার করতে পারেন বা আপনি getContext () পদ্ধতি ব্যবহার করতে পারেন।

 View root = inflater.inflate(R.layout.fragment_slideshow, container, false);
    Context c = root.getContext();

আমি আসা করি এটা সাহায্য করবে!


1
অন্যান্য উত্তরগুলি রয়েছে যা ওপির প্রশ্ন সরবরাহ করে এবং কিছু সময় আগে সেগুলি পোস্ট করা হয়েছিল। উত্তর পোস্ট করার সময় দেখুন: আমি কীভাবে ভাল উত্তর লিখব? , দয়া করে নিশ্চিত হয়ে নিন যে আপনি কোনও নতুন সমাধান যুক্ত করেছেন, বা যথেষ্ট উত্তম ব্যাখ্যা, বিশেষত পুরানো প্রশ্নের উত্তর দেওয়ার সময়।
help-info.de

0

getContext () পদ্ধতিটি খণ্ড ক্রিয়াকলাপে শ্রেণীর প্রসঙ্গটি ব্যবহার করতে সহায়তা করে।


0

আমি মনে করি আপনি ব্যবহার করতে পারেন

public static class MyFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

      Context context = getActivity.getContext();

  }
}

0
public class MenuFragment extends Fragment implements View.OnClickListener {
    private Context mContext;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentMenuBinding binding=FragmentMenuBinding.inflate(inflater,container,false);
        View view=binding.getRoot();
        mContext=view.getContext();
        return view;
    }
}

0

এছাড়াও আপনি ব্যবহার করতে পারেন:

inflater.getContext();

তবে আমি ব্যবহার করতে পছন্দ করব

getActivity()

অথবা

getContext

0

অ্যারেএডাপ্টার ইন টুকরোটি ব্যবহার করার জন্য আমার প্রসঙ্গটি দরকার, যখন আমি getActivity ত্রুটিটি ব্যবহার করছিলাম তবে আমি যখন এটি getContext এর সাথে প্রতিস্থাপন করি তখন এটি আমার জন্য কাজ করে

listView LV=getView().findViewById(R.id.listOFsensors);
LV.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1 ,listSensorType));

0

আপনি ব্যবহার করতে পারেন getActivity()বা getContextখণ্ডে।

নথিপত্র

/**
 * Return the {@link FragmentActivity} this fragment is currently associated with.
 * May return {@code null} if the fragment is associated with a {@link Context}
 * instead.
 *
 * @see #requireActivity()
 */
@Nullable
final public FragmentActivity getActivity() {
    return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}

এবং

 /**
     * Return the {@link Context} this fragment is currently associated with.
     *
     * @see #requireContext()
     */
    @Nullable
    public Context getContext() {
        return mHost == null ? null : mHost.getContext();
    }

প্রো টিপ

সর্বদা পরীক্ষা করুন if(getActivity!=null)কারণ খণ্ডটি ক্রিয়াকলাপের সাথে সংযুক্ত না হলে এটি নাল হতে পারে । কখনও কখনও খণ্ডে দীর্ঘ অপারেশন করতে (যেমন বাকি এপিআই থেকে ডেটা আনতে) কিছুটা সময় নেয়। এবং যদি ব্যবহারকারী অন্য খণ্ডে নেভিগেট করে। তারপরে getActivity নਾਲ হবে। এবং যদি আপনি এটি পরিচালনা না করেন তবে আপনি এনপিই পাবেন।


এটি getActivity () পদ্ধতির একটি ডকুমেন্টেশন, কেবল এগুলি নাল হতে পারে তা দেখানোর জন্য। এখানে এমহস্ট FragmentHostCallbackক্লাসের উদাহরণ ।
খেমরাজ

0

আপনি খণ্ডিত

((Name_of_your_Activity) getActivity()).helper

ক্রিয়াকলাপে

DbHelper helper = new DbHelper(this);

0

কোটলিন নমুনার জন্য ভিতরে ভিতরে খণ্ড কারও সাহায্য করবে

textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

আপনি যদি ডেটাবাইন্ডিং ব্যবহার করেন;

bindingView.textViewStatus.setTextColor(ContextCompat.getColor(context!!, R.color.red))

কোথায় bindingView মধ্যে সক্রিয়া করা হয় onCreateView ভালো

private lateinit var bindingView: FragmentBookingHistoryDetailBinding

bindingView = DataBindingUtil.inflate(inflater, R.layout.your_layout_xml, container, false)

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