我有一个活动,只要点击cpt_loader
按钮就会加载片段bookings
。 cpt_loader
显示循环进度条,直到使用MySQL database
从Volley library
获取数据。收到响应后,cpt_loader
会立即使用接口将JSONObject发送到MainActivity
。它完美地工作到这一点,数据也在MainActivity
中收到。但是,当我使用接口再次从MainActivity
向bookings
片段发送JSONObject时,我得到:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.user.temporary.MainActivity$sendCPTToBookings.sendToBookings(org.json.JSONObject)' on a null object reference
MainActivity.java中的代码:
package com.example.user.temporary;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity implements
cpt_loader.sendCPTToMainActivity {
sendCPTToBookings sendListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout profilebtn = (LinearLayout)this.findViewById(R.id.profile_button);
LinearLayout bookingsbtn = (LinearLayout)this.findViewById(R.id.bookings_button);
LinearLayout gamesbtn = (LinearLayout)this.findViewById(R.id.games_button);
bookingsbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cpt_loader loader_frame = new cpt_loader();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.fragment_frame, loader_frame);
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
trans.commit();
}
});
}
@Override
public void sendCPT(JSONObject cpt_json){
sendListener.sendToBookings(cpt_json);
}
public interface sendCPTToBookings {
void sendToBookings(JSONObject cpt_json);
}
}
cpt_loader.java中的代码:
package com.example.user.temporary;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class cpt_loader extends Fragment {
RequestQueue requestQueue;
final String dataUrl = "http://10.0.2.2/futsal/main.php";
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private sendCPTToMainActivity mListener;
public cpt_loader() {
// Required empty public constructor
}
public static cpt_loader newInstance(String param1, String param2) {
cpt_loader fragment = new cpt_loader();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_cpt_loader, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
final ArrayList<String> cities_array = new ArrayList<String>();
super.onViewCreated(view, savedInstanceState);
final RelativeLayout ld = (RelativeLayout)getView().findViewById(R.id.loader);
final RelativeLayout fb = (RelativeLayout)getView().findViewById(R.id.form_body);
final Spinner city_sp = (Spinner)getView().findViewById(R.id.city_sp);
requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, dataUrl, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try{
bookings bookings_frame = new bookings();
FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
trans.replace(R.id.fragment_frame, bookings_frame);
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
trans.commit();
mListener.sendCPT(response);
} catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
requestQueue.add(jsonObjectRequest);
}
public void onButtonPressed(JSONObject json) {
if (mListener != null) {
mListener.sendCPT(json);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof sendCPTToMainActivity) {
mListener = (sendCPTToMainActivity) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface sendCPTToMainActivity {
void sendCPT(JSONObject cpt_json);
}
}
bookings.java中的代码:
package com.example.user.temporary;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.volley.RequestQueue;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class bookings extends Fragment implements MainActivity.sendCPTToBookings{
private long L1;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public bookings() {
// Required empty public constructor
}
public static bookings newInstance(String param1, String param2) {
bookings fragment = new bookings();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_bookings, container, false);
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
public void sendToBookings(JSONObject json_obj){
try{
JSONArray cities = json_obj.getJSONArray("city");
int num_cities = cities.length();
for(int i=0;i<num_cities;i++) {
System.out.println(cities.getString(i));
}
} catch (JSONException e){
e.printStackTrace();
}
}
}
此外,在此link的官方Android文档中,数据从片段传递到活动,但与我的应用程序相反,活动直接处理第二个片段中的视图。我不知道一个活动是否能够使用接口向片段发送数据。
答案 0 :(得分:1)
这不会这样。这是2个问题:
sendListener
sendListener
片段初始化bookings
,它可能无法一直有效。因为无法保证bookings
会在您致电MainActivity
之前初始化并附加到mListener.sendCPT(response);
。如果在调用bookings
之前未创建并附加mListener.sendCPT(response);
片段,则您的sendListener
将为空。创建sendListener
Fragment并附加到Activity后,bookings
将有效。你可以用其他方式做到。您可以将JSONObject
保存在MainActivity
中。当bookings
片段附加到MainActivity时,您只需从getMeJson()
片段调用MainActivity方法bookings
即可。并检查是否为空或有效。
<强> MainActivity 强>
JSONObject jsonObject;
@Override
public void sendCPT(JSONObject cpt_json){
jsonObject = cpt_json;
}
public JSONObject getMeJson(){
return jsonObject;
}
预订片段
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MainActivity) {
MainActivity activity = (MainActivity)context;
JSONObject jsonObject = activity.getMeJson():
}
}
答案 1 :(得分:0)
我发现使用setter或其他函数而不是接口发送数据TO Fragments更容易。
Fragment targetFragment = GetFragmentManager.findFragmentByTag("targetFragment ");
if(targetFragment != null){
((MyFragmentClass) targetFragment).receiveData(data);
}