我正在使用 Fragments,当我快速按下后退按钮时,应用程序崩溃了。它随机发生
Posted
技术标签:
【中文标题】我正在使用 Fragments,当我快速按下后退按钮时,应用程序崩溃了。它随机发生【英文标题】:I'm using Fragments and when I press the back button really fast the app crashes. It happens randomly 【发布时间】:2018-07-04 06:18:16 【问题描述】:我正在使用 Fragments,当我快速按下后退按钮时,android 应用程序崩溃了。它是随机发生的,这里是java代码:
public class PlayerFragment extends Fragment
List<County> feeds;
String action = "counties";
private static MediaPlayer mMediaPlayer;
TextView descr;
TextView feed_id;
TextView status;
TextView listeners;
TextView genre;
TextView bitrate;
private static Button switchButton;
private AdView mAdView;
InterstitialAd mInterstitialAd;
public PlayerFragment()
// Required empty public constructor
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_player, container, false);
//view called and initialized
initView(rootView);
updateView();
AdRequest adRequest = new AdRequest.Builder()
.build();
mAdView.loadAd(adRequest);
// set the ad unit ID
mInterstitialAd.setAdUnitId(getString(R.string.interstitial_full_screen));
// Load ads into Interstitial Ads
mInterstitialAd.loadAd(adRequest);
mInterstitialAd.setAdListener(new AdListener()
public void onAdLoaded()
showInterstitial();
);
final Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(RadioApiClient.BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
RadioApiClient client = retrofit.create(RadioApiClient.class);
Call<Counties> call = client.getCounties(action,
BrowseStateFragment.stateId,
RadioApiClient.JSON_RESPONSE,
RadioApiClient.API_KEY);
Log.d("Accessing url", client.getCounties(action, BrowseStateFragment.stateId,
RadioApiClient.JSON_RESPONSE,
RadioApiClient.API_KEY).request().url().toString());
call.enqueue(new Callback<Counties>()
@Override
public void onResponse(Call<Counties> call, Response<Counties> response)
feeds = response.body().getCounties();
AudioManager amanager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
int maxVolume = amanager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
amanager.setStreamVolume(AudioManager.STREAM_ALARM, maxVolume, 0);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudiostreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
@Override
public void onPrepared(MediaPlayer mp)
togglePlayPause();
);
String station = BrowseFeedsFragment.station;
Toast.makeText(getActivity(), "Setting radio", Toast.LENGTH_LONG).show();
if (mMediaPlayer.isPlaying())
mMediaPlayer.stop();
Toast.makeText(getActivity(), "stopping radio", Toast.LENGTH_LONG).show();
mMediaPlayer.reset();
Toast.makeText(getActivity(), "resetting radio", Toast.LENGTH_LONG).show();
try
Toast.makeText(getActivity(), "Trying to play ", Toast.LENGTH_LONG).show();
mMediaPlayer.setDataSource(station);
mMediaPlayer.prepareAsync();
mMediaPlayer.start();
showInterstitial();
Toast.makeText(getActivity(), "playing", Toast.LENGTH_LONG).show();
catch (IOException e)
e.printStackTrace();
@Override
public void onFailure(Call<Counties> call, Throwable t)
Log.d("no success", "" + "onfailure");
t.printStackTrace();
);
// Inflate the layout for this fragment
return rootView;
@Override
public void onAttach(Activity activity)
super.onAttach(activity);
@Override
public void onPause()
if (mAdView != null)
mAdView.pause();
super.onPause();
@Override
public void onResume()
super.onResume();
if (mAdView != null)
mAdView.resume();
showInterstitial();
@Override
public void onDestroy()
if (mAdView != null)
mAdView.destroy();
super.onDestroy();
@Override
public void onDetach()
super.onDetach();
private void togglePlayPause()
if (mMediaPlayer.isPlaying())
mMediaPlayer.pause();
switchButton.setText("Play");
Toast.makeText(getActivity(), "Paused", Toast.LENGTH_LONG).show();
else
mMediaPlayer.start();
switchButton.setText("Pause");
Toast.makeText(getActivity(), "Playing", Toast.LENGTH_LONG).show();
private void showInterstitial()
if (mInterstitialAd.isLoaded())
mInterstitialAd.show();
public void initView(View rootView)
descr = (TextView) rootView.findViewById(R.id.descr);
feed_id = (TextView) rootView.findViewById(R.id.feed_id);
status = (TextView) rootView.findViewById(R.id.status);
listeners = (TextView) rootView.findViewById(R.id.listeners);
genre = (TextView) rootView.findViewById(R.id.genre);
bitrate = (TextView) rootView.findViewById(R.id.bitrate);
switchButton = (Button) rootView.findViewById(R.id.switchButton);
mAdView = (AdView) rootView.findViewById(R.id.adView);
mInterstitialAd = new InterstitialAd(getActivity());
public void updateView()
//update views
descr.setText("Description: " + BrowseFeedsFragment.descr);
feed_id.setText("Feed Id: " + BrowseFeedsFragment.feed_id);
if (BrowseFeedsFragment.status == "1")
status.setText("Status: " + "Live Streaming Active");
else
status.setText("Status: " + "Live Streaming Offline");
listeners.setText("Listerners: " + BrowseFeedsFragment.listeners);
genre.setText("Genre: " + BrowseFeedsFragment.genre);
bitrate.setText("Bitrate: " + BrowseFeedsFragment.bitrate + "KBPS");
Log.d("Success", "" + "Update Success");
//event handling
switchButton.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
togglePlayPause();
);
我收到的错误消息是这样的:
> FATAL EXCEPTION: main
> Process: com.kwawannan.policedispatchlivescanner, PID: 27704
> java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null
> object reference
> at android.widget.Toast.<init>(Toast.java:103)
> at android.widget.Toast.makeText(Toast.java:256)
> at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.togglePlayPause(PlayerFragment.java:208)
> at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.access$200(PlayerFragment.java:36)
> at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment$2$1.onPrepared(PlayerFragment.java:123)
> at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2872)
> at android.os.Handler.dispatchMessage(Handler.java:102)
> at android.os.Looper.loop(Looper.java:154)
> at android.app.ActivityThread.main(ActivityThread.java:6119)
> at java.lang.reflect.Method.invoke(Native Method)
> at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
> at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
【问题讨论】:
可能是它的副本 - ***.com/questions/28515049/… 你在某处展示了无效上下文的吐司 我应该使用什么上下文? 【参考方案1】:这是因为onResponse
在片段被销毁并与活动分离后被调用。
正确的解决方案是在片段被销毁时取消或处理调用:
在onDestroyView
中调用call.cancel()
或call.dispose
方法
【讨论】:
如何使用 call.cancel() ,调用在我的代码中是未知的 在 onCreateView 中创建调用Call<Counties> call = client.getCountie ...
只需使其成为类成员,这样您就可以在 destroy 中访问它
调用 call.cancel() 后仍然会发生
'java.lang.String android.content.Context.getPackageName()' 在空对象引用上,在 com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.togglePlayPause(PlayerFragment.java:210) 在com.kwawannan.policedispatchlivescanner.activity.PlayerFragment.access$200(PlayerFragment.java:36) at com.kwawannan.policedispatchlivescanner.activity.PlayerFragment$2$1.onPrepared(PlayerFragment.java:124)【参考方案2】:
如显示错误代码。
com.kwawannan.policedispatchlivescanner, PID: 27704 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference at android.widget.Toast.(Toast.java:103)
你应该使用 getContext() 而不是 getActivity();喜欢
Toast.makeText(getContext(), "msg text", Toast.LENGTH_LONG).show();
【讨论】:
【参考方案3】:像下面这样改变你的切换方法:
private void togglePlayPause()
Activity activity = getActivity();
if (mMediaPlayer!=null && activity!=null)
if (mMediaPlayer.isPlaying())
mMediaPlayer.pause();
switchButton.setText("Play");
Toast.makeText(activity, "Paused", Toast.LENGTH_LONG).show();
else
mMediaPlayer.start();
switchButton.setText("Pause");
Toast.makeText(activity, "Playing", Toast.LENGTH_LONG).show();
希望对你有帮助。
【讨论】:
以上是关于我正在使用 Fragments,当我快速按下后退按钮时,应用程序崩溃了。它随机发生的主要内容,如果未能解决你的问题,请参考以下文章
如何为Android Fragments(Tabs Activity)实现onBackPressed