0

I want pass my String json from fragment to another activity so make interface between fragment and activity but when lunch app get null exception from this line from my fragment :adapterCalljson.MethodCallbackjson(jsonStr);

this is my try so far :

interface class :

public interface AdapterCalljson {
    void MethodCallbackjson(String jsonn);
}

fragment :

 public class maghalat extends Fragment {

    private View myFragmentView;
    private RecyclerView recyclerView;
    private DataAdapter adapter;
    private String TAG = MainActivity.class.getSimpleName();
    public ProgressDialog pDialog;
    List<jsonContent> listcontent=new ArrayList<>();

    public int dog=1;
    public String url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";

    public int id;

   AdapterCalljson adapterCalljson;

    public String json;
    public String jsonStr;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof AdapterCalljson) {
            adapterCalljson = (AdapterCalljson) context;
        } else {
            throw new RuntimeException(context + " must implement AdapterCalljson");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        adapterCalljson = null;
    }
    public interface AdapterCalljson {

        void MethodCallbackjson(String json);

    }

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


        adapterCalljson.MethodCallbackjson(json);
        asyncRun();


        return myFragmentView;
    }
        public void asyncRun(){
        if(isNetworkConnected()) {
            new GetContacts().execute();
        } else
        {
            Toast.makeText(getActivity().getApplicationContext(), "دستگاه شما به اینترنت متصل نیست!", Toast.LENGTH_LONG).show();
        }
    }


    public class GetContacts extends AsyncTask<Void, Void, Void> {


    @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();
        }

        @Override
        protected Void doInBackground(Void... arg0) {

            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response
          jsonStr = sh.makeServiceCall(url);


            Log.e(TAG, "Response from url: " + jsonStr);

            if (jsonStr != null) {
                try {

                    JSONObject jsonObj = new JSONObject(jsonStr);




                     id=jsonObj.getInt("pages");

                    JSONArray posts = jsonObj.getJSONArray("posts");

                    for (int i = 0; i < posts.length(); i++) {
                        JSONObject c = posts.getJSONObject(i);

                        jsonContent jsonContent=new jsonContent();

                        jsonContent.title=c.getString("title");

                        jsonContent.content=c.getString("content");

                        //img
                        JSONObject post_img=c.getJSONObject("thumbnail_images");
                        for (int j=0;j<post_img.length();j++)
                        {
                            JSONObject v=post_img.getJSONObject("mom-portfolio-two");
                            jsonContent.imgurl=v.getString("url");
                        }
                        jsonContent.pages=id;
                        jsonContent.curpage=dog;
                        listcontent.add(jsonContent);

                    }

                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getActivity().getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG)
                                    .show();
                        }
                    });
                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getActivity().getApplicationContext(),
                                "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            pDialog.dismiss();
            recyclerView=(RecyclerView)myFragmentView.findViewById(R.id.recycler_view);
            recyclerView.setHasFixedSize(true);
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
            recyclerView.setLayoutManager(layoutManager);

            adapter=new DataAdapter(getActivity(), listcontent, new AdapterCallback() {
                @Override
                public void MethodCallbackgo(String data) {

                    Integer s=null;
                    try {
                        s= Integer.valueOf(data);
                    }catch (NumberFormatException e)
                    {
                    }
                    if (s!=null && s>=1 && s<=id)
                    {
                        dog= Integer.parseInt(data);
                        url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
                        new GetContacts().execute();
                    }else
                    {
                        Toast.makeText(getActivity().getApplicationContext(),"صفحه پیدا نشد",Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void MethodCallbacknext() {

                    if (dog<id)
                    {
                        dog += 1;
                        url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
                        new GetContacts().execute();

                    }else {
                        Toast.makeText(getActivity().getApplicationContext(),"این آخرین صفحه است",Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void MethodCallbackprev() {
                    if (dog!=1)
                    {
                        dog-=1;
                        url = "http://memaraneha.ir/category/%d9%85%d9%82%d8%a7%d9%84%d8%a7%d8%aa/page/"+String.valueOf(dog)+"/?json=get_recent_posts";
                        new GetContacts().execute();
                    }else{
                        Toast.makeText(getActivity().getApplicationContext(),"این اولین صفحه است",Toast.LENGTH_SHORT).show();
                    }
                }
            });
            recyclerView.setAdapter(adapter);

            json=jsonStr;


        }
    }
Erf
  • 343
  • 1
  • 3
  • 11
  • Um. You never assigned `adapterCalljson` to anything. – OneCricketeer Jan 13 '17 at 16:43
  • your adapter is null chum, you should have a null check – Saik Caskey Jan 13 '17 at 16:43
  • Besides that point, I don't think you understand how "async" works. `jsonStr` is also null at the point where you call that method – OneCricketeer Jan 13 '17 at 16:44
  • 1
    go through [this link carefully](https://developer.android.com/training/basics/fragments/communicating.html) – Pavneet_Singh Jan 13 '17 at 16:45
  • @cricket_007 please answer my question and tell how where my code must be change – Erf Jan 13 '17 at 17:36
  • I can't tell what is implementing your interface, but if you want JSON + Callbacks + Network requests, use Volley or Retrofit. You don't need to force yourself into the complexity of AsyncTasks – OneCricketeer Jan 13 '17 at 17:55
  • @cricket_007 i just want pass 1 string data from this fragment to another activity . how can do that ? – Erf Jan 13 '17 at 18:01
  • 1) Actually assign the callback to something 2) From `onPostExecute`, you pass back the `jsonStr`. OR, your other option is to move the entire AsyncTask to the Activity where you need the data – OneCricketeer Jan 13 '17 at 18:06
  • @cricket_007 look at my edited question – Erf Jan 13 '17 at 18:16
  • Okay, what about it? Does the activity implement the interface? You still cannot call `adapterCalljson.MethodCallbackjson(json);` from within onCreate. There *is no JSON* at that point. – OneCricketeer Jan 13 '17 at 18:22
  • @cricket_007 why i cant ? i just want pass my jsonStr in my do in background to String of my adapter method it mean String json – Erf Jan 13 '17 at 18:25
  • Because 1) The Activity is not yet attached when `onCreateView` is called. The callback is null. 2) The json is null because the AsyncTask has not assigned it yet. – OneCricketeer Jan 13 '17 at 18:27
  • ok you right . at last you can fix my problem ? – Erf Jan 13 '17 at 18:29
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – David Rawson Jan 14 '17 at 19:20

2 Answers2

0

You haven't assigned an object to adapterCalljson. Assuming you're implementing AdapterCalljson in the host activity, assign it from the context onAttach:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof AdapterCalljson) {
        adapterCalljson = (AdapterCalljson) context;
    } else {
        throw new RuntimeException(context + " must implement AdapterCalljson");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    adapterCalljson = null;
}

public interface AdapterCalljson {

    void MethodCallbackjson(String json);

}
ditn
  • 1,386
  • 1
  • 10
  • 23
  • so i add your part of codes in my fragment but get null exception from this line : throw new RuntimeException(context + " must implement AdapterCalljson"); – Erf Jan 13 '17 at 17:57
  • @user7415865 Nothing on that line throws a null pointer exception. You are probably getting a `RuntimeException` for the exact reason that is written there. The Activity **must implement AdapterCalljson** – OneCricketeer Jan 13 '17 at 18:07
0

Firstly, your Activity containing the Fragment must implement that interface.

public class MainActivity implements AdapterCalljson {

    @Override  
    void MethodCallbackjson(String jsonn) {
        doSomethingWithJson(jsonn);
    }    

    private void doSomethingWithJson(String json) {

    }

    // onCreate...

}

Next, I would recommend you create the RecyclerView outside the AsyncTask. You don't need to save the myFragmentView variable.

Additionally, you can't call the callback yet. There is no data.

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

    // recyclerView = rootView.findViewById
    // adapter = ...
    // recyclerView.setAdadpter...

    asyncRun(); // This happens in the background. There is no JSON yet

    return rootView;
}

Then, perhaps you should have doInBackground return the JSON string so you don't have to store it as a class variable.

The last argument is the return type.

public class GetContacts extends AsyncTask<Void, Void, String>

So, then it is public String doInBackground(Void params...) {} and public void onPostExecute(String result) {}.

In other words, don't just return null from doInBackground

@Override
protected String doInBackground(Void... arg0) {

    HttpHandler sh = new HttpHandler();

    // Making a request to url and getting response
    jsonStr = sh.makeServiceCall(url);

    // Parse JSON more...

    return jsonStr;
}

And then you should be able to use your callback.

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);

    pDialog.dismiss();
    if (adapterCalljson != null) {
        adapterCalljson.MethodCallbackjson(result);
    } else {
        Log.w("Callback Error", "callback not assigned");
    }

    // adapter.notifyDataSetChanged(); // Might want this 
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245