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