Android 截击响应前碎片更改时应用程序崩溃

Android 截击响应前碎片更改时应用程序崩溃,android,android-volley,Android,Android Volley,我有底部导航视图,其中有3个片段,分别命名为Home、Notifications和Account。在Home fragment中,我使用用户最后已知的位置发出截击post请求,并在此基础上从服务器获取响应。我想知道: 当我在截击响应之前的片段之间切换时,我的应用程序崩溃,当我在响应完成后切换时,没有应用程序崩溃 当活动第一次启动时,服务器的响应不显示。它显示我在片段之间切换并再次返回时的响应 它将显示错误日志: java.lang.NullPointerException: Attempt t

我有底部导航视图,其中有3个片段,分别命名为Home、Notifications和Account。在Home fragment中,我使用用户最后已知的位置发出截击post请求,并在此基础上从服务器获取响应。我想知道:

  • 当我在截击响应之前的片段之间切换时,我的应用程序崩溃,当我在响应完成后切换时,没有应用程序崩溃

  • 当活动第一次启动时,服务器的响应不显示。它显示我在片段之间切换并再次返回时的响应

  • 它将显示错误日志:

     java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
        at android.widget.Toast.<init>(Toast.java:138)
        at android.widget.Toast.makeText(Toast.java:385)
        at tiffino.app.com.Home$1.onResponse(Home.java:245)
        at tiffino.app.com.Home$1.onResponse(Home.java:240)
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
        at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
    
    java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.content.res.Resources android.content.Context.getResources()”
    在android.widget.Toast.(Toast.java:138)
    位于android.widget.Toast.makeText(Toast.java:385)
    在tiffino.app.com.Home$1.onResponse(Home.java:245)
    在tiffino.app.com.Home$1.onResponse(Home.java:240)
    位于com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
    位于com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
    位于com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
    位于android.os.Handler.handleCallback(Handler.java:751)
    位于android.os.Handler.dispatchMessage(Handler.java:95)
    位于android.os.Looper.loop(Looper.java:154)
    位于android.app.ActivityThread.main(ActivityThread.java:6776)
    位于java.lang.reflect.Method.invoke(本机方法)
    在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run上(ZygoteInit.java:1496)
    位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
    
    Home.java

    public class Home extends Fragment implements GoogleApiClient.OnConnectionFailedListener,
        GoogleApiClient.ConnectionCallbacks,
        com.google.android.gms.location.LocationListener {
    
        TextView fragText;
        GoogleApiClient mGoogleApiClient;
        LocationRequest mLocationRequest;
        Location mLocation;
        RequestQueue requestQueue;
        StringRequest stringRequest;
        public static final String TAG = "MyTag";
        private static final String URL = "https://google.com";
    
        public Home() { }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.fragment_home, container, false);
    
            fragText = view.findViewById(R.id.fragText);
    
            mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    
            return view;
        }
    
    
        @Override
        public void onStart() {
            super.onStart();
            mGoogleApiClient.connect();
        }
    
        @Override
        public void onStop() {
            super.onStop();
            if(mGoogleApiClient.isConnected() && requestQueue != null){
                mGoogleApiClient.disconnect();
                requestQueue.cancelAll(TAG);
            }
        }
    
        @Override
        public void onConnected(@Nullable Bundle bundle) {
            mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if(mLocation != null) {
                String str1 = hereLocation(mLocation.getLatitude(),mLocation.getLongitude());
                fragText.setText(str1);
                sendLocation(str1);
            }
        }
    
        @Override
        public void onConnectionSuspended(int i) { }
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { }
    
        private void sendLocation(final String str1) {
            requestQueue = Volley.newRequestQueue(getContext());
            stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Toast.makeText(getActivity(),""+response,Toast.LENGTH_SHORT).show();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) { }
            }) {
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    HashMap<String,String> map = new HashMap<>();
                    map.put("name",str1);
                    return map;
                }   
            };
            stringRequest.setTag(TAG);
            requestQueue.add(stringRequest);
        }
    
        private String hereLocation(double lat, double lon) {
            String city = "";
            Geocoder geo = new Geocoder(getContext(), Locale.getDefault());
            List<Address> addresses;
            try {
                addresses = geo.getFromLocation(lat,lon,10);
                if(addresses.size()>0) {
                    for (Address adr: addresses) {
                        if(adr.getLocality()!=null && adr.getLocality().length()>0) {
                            city = adr.getLocality();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return city;
        }
    }
    
    公共类Home extends片段实现了GoogleAppClient.OnConnectionFailedListener,
    GoogleAppClient.ConnectionCallbacks,
    com.google.android.gms.location.LocationListener{
    文本视图fragText;
    GoogleapClient MGoogleapClient;
    位置请求mLocationRequest;
    位置;
    请求队列请求队列;
    StringRequest-StringRequest;
    公共静态最终字符串TAG=“MyTag”;
    私有静态最终字符串URL=”https://google.com";
    公共住宅(){}
    @凌驾
    创建视图上的公共视图(布局、充气机、视图组容器、,
    Bundle savedInstanceState){
    //为该碎片膨胀布局
    视图=充气机。充气(R.layout.fragment\u home,container,false);
    fragText=view.findviewbyd(R.id.fragText);
    mgoogleapclient=新的Googleapclient.Builder(getActivity())
    .addConnectionCallbacks(此)
    .addOnConnectionFailedListener(此)
    .addApi(LocationServices.API)
    .build();
    返回视图;
    }
    @凌驾
    public void onStart(){
    super.onStart();
    mGoogleApiClient.connect();
    }
    @凌驾
    公共void onStop(){
    super.onStop();
    if(mgoogleapclient.isConnected()&&requestQueue!=null){
    mGoogleApiClient.disconnect();
    requestQueue.cancelAll(标记);
    }
    }
    @凌驾
    未连接的公共无效(@Nullable Bundle){
    mLocation=LocationServices.FusedLocationApi.getLastLocation(mgoogleapClient);
    如果(mLocation!=null){
    字符串str1=hereLocation(mLocation.getLatitude(),mLocation.getLatitude());
    fragText.setText(str1);
    发送位置(str1);
    }
    }
    @凌驾
    连接已暂停(int i){}
    @凌驾
    public void onConnectionFailed(@NonNull ConnectionResult ConnectionResult){}
    私有void sendLocation(最终字符串str1){
    requestQueue=Volley.newRequestQueue(getContext());
    stringRequest=newStringRequest(Request.Method.POST,URL,new Response.Listener()){
    @凌驾
    公共void onResponse(字符串响应){
    Toast.makeText(getActivity(),“”+response,Toast.LENGTH_SHORT).show();
    }
    },new Response.ErrorListener(){
    @凌驾
    公共无效onErrorResponse(截击错误){}
    }) {
    @凌驾
    受保护的映射getParams()引发AuthFailureError{
    HashMap=newHashMap();
    map.put(“名称”,str1);
    返回图;
    }   
    };
    stringRequest.setTag(TAG);
    添加(stringRequest);
    }
    专用字符串位置(双lat,双lon){
    字符串城市=”;
    Geocoder geo=新的地理编码器(getContext(),Locale.getDefault());
    列出地址;
    试一试{
    地址=地理位置getFromLocation(纬度,经度,10);
    如果(地址.size()>0){
    地址(adr:地址){
    if(adr.getLocality()!=null&&adr.getLocality().length()>0){
    city=adr.getLocation();
    }
    }
    }
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    回归城市;
    }
    }
    
    请让我知道应用程序崩溃的原因


    谢谢

    问题可能出在onRespones中的getActivity()上。由于您现在位于另一个片段中,因此该片段现在未附加到getActivity

    你可以做:

    if(isAdded()) { 
       Toast.makeText(getActivity(),""+response,Toast.LENGTH_SHORT).show();
    }
    

    问题可能出在onRespones中的getActivity()上。由于您现在位于另一个片段中,因此该片段现在未附加到getActivity

    你可以做:

    if(isAdded()) { 
       Toast.makeText(getActivity(),""+response,Toast.LENGTH_SHORT).show();
    }
    

    尽管如此,您还没有提供一段代码。但一般来说,我可以告诉您,当您使用一些回调方法创建web请求时,应该注意很多事情。 例如,假设您有以下代码:

    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://www.google.com";
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            mTextView.setText(response);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    });
    // Set the tag on the request.
    stringRequest.setTag(TAG);
    
    // Add the request to the RequestQueue.
    queue.add(stringRequest);
    
    另一个选项是在尝试进行sinc更改之前检查片段状态
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                    new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (isResumed())
                {
                    mTextView.setText(response);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (isResumed())
                {
                    mTextView.setText("That didn't work!");
                }
            }
        });
    
    public class MainActivity extends FragmentActivity implements Response.Listener, Response.ErrorListener {
    
        ...
        @Override
        public void onResponse(String response) {
            if(response != null) {
                Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
            }
        }
    
        @Override
        public void onErrorResponse(VolleyError error) {
    
        }
    }
    
    new StringRequest(Request.Method.GET, url, getActivity());