首页 > 解决方案 > 当手机屏幕关闭或休眠时,片段布局退出我的应用程序

问题描述

我需要帮助,我正在使用片段来保存项目列表,但是当片段布局是屏幕上的活动布局时,当手机屏幕灯关闭或休眠时,它会退出应用程序。请问,可能是什么原因?

这是我下面的代码:

列表项的片段布局

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".BookChapters">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:clipChildren="false"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="350dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleGravity="bottom|center_horizontal"
        android:clipChildren="false">

        <ImageView
            android:id="@+id/header_book_image"
            android:layout_width="match_parent"
            android:layout_height="350dp"
            android:fitsSystemWindows="true"
            android:src="@drawable/default_book"
            android:scaleType="centerCrop"
            app:layout_collapseMode="parallax"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/chapterList_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    </android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
    android:id="@+id/chapters_recycler"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

片段 BookChapters.java 类

public class BookChapters extends Fragment implements ChapterListAdapter.ListItemClickListener, Player.EventListener{
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnChapterSelectedListener mListener;

ImageView bookImage;
ArrayList<Chapter> chapters;
RecyclerView chaptersRecycler;
ChapterListAdapter adapter;

Toolbar mToolbar;

private MediaSource mediaSource;
private SimpleExoPlayer player;
static MediaSessionCompat mMediaSession;
PlaybackStateCompat.Builder playbackState;
PlaybackStateCompat.Builder mStateBuilder;
NotificationManager mNotificationManager;

private boolean playWhenReady = true;
private int currentWindow = 0;
private long playbackPosition = 0;
private int currentPosition = 0;

private int MEDIA_PLAYING_STATE = 0;

private static final String CHANNEL_ID = "media_playback_channel";
private static final int NOTIFICATION_ID = 100;

ChaptersPagerAdapter chaptersPagerAdapter;
int activePosition = 0;

PlayerNotificationManager playerNotificationManager;

public BookChapters() {
    // Required empty public constructor
}

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param param1 Parameter 1.
 * @param param2 Parameter 2.
 * @return A new instance of fragment BookChapters.
 */
// TODO: Rename and change types and number of parameters
public static BookChapters newInstance(String param1, String param2) {
    BookChapters fragment = new BookChapters();
    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);
    }
}


@SuppressLint("NewApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_book_chapters, container, false);

    mMediaSession = new MediaSessionCompat(getActivity(), "TAG");
    mMediaSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
            MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
    mMediaSession.setMediaButtonReceiver(null);

    mStateBuilder = new PlaybackStateCompat.Builder();
    playbackState = new PlaybackStateCompat.Builder().setActions(PlaybackState.ACTION_PLAY |
    PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_FAST_FORWARD |
    PlaybackState.ACTION_PLAY_PAUSE | PlaybackState.ACTION_SKIP_TO_NEXT |
    PlaybackState.ACTION_SKIP_TO_PREVIOUS | PlaybackState.ACTION_REWIND);

    mMediaSession.setPlaybackState(playbackState.build());
    mMediaSession.setCallback(new mySessionCallback());
    mMediaSession.setActive(true);

    playerNotificationManager = new PlayerNotificationManager(
        getActivity(),
        CHANNEL_ID,
        NOTIFICATION_ID, new DescriptionAdapter());

    PowerManager powerManager = (PowerManager) getActivity().getSystemService(POWER_SERVICE);
    PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
            "MyApp::MyWakelockTag");
    wakeLock.acquire();

    // omit fast forward action by setting the increment to zero
    playerNotificationManager.setFastForwardIncrementMs(0);
    // omit rewind action by setting the increment to zero
    playerNotificationManager.setRewindIncrementMs(0);
    // omit the stop action
    playerNotificationManager.setStopAction(null);
    playerNotificationManager.setSmallIcon(R.drawable.talking_bookz);

    mToolbar = (Toolbar) view.findViewById(R.id.chapterList_toolbar);
    ((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);

    String bookTitle = this.getArguments().getString("book_title");

    ActionBar supportActionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
    if (supportActionBar != null){
        supportActionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back_black_24dp);
        supportActionBar.setDisplayHomeAsUpEnabled(true);
        supportActionBar.setTitle(bookTitle);
    }

    String book_image = this.getArguments().getString("book_design");
    bookImage = (ImageView) view.findViewById(R.id.header_book_image);
    volleyImageLoader(book_image);

    chaptersRecycler = (RecyclerView) view.findViewById(R.id.chapters_recycler);
    chaptersRecycler.setLayoutManager(new LinearLayoutManager(getContext(),
            LinearLayoutManager.VERTICAL, false));

    chapters = (ArrayList<Chapter>) this.getArguments().getSerializable("chapters");

    adapter = new ChapterListAdapter(getContext(), chapters, this);
    chaptersRecycler.setAdapter(adapter);


    chaptersPagerAdapter = new ChaptersPagerAdapter(getContext(), chapters);
    ((MainActivity) getActivity()).chaptersRecycler.setAdapter(chaptersPagerAdapter);

    return view;
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (player.getPlaybackState() == ExoPlayer.STATE_READY) {
        player.setPlayWhenReady(true);
    }
}

// TODO: Rename method, update argument and hook method into UI event
public void setOnBookChapterSelected(Uri uri) {
    if (mListener != null) {
        mListener.onChapterSelected(uri);
    }
}

@Override
public void onListItemClick(int position) {
    Chapter chapter = chapters.get(position);
    String url = chapter.getChapterAudioUrl();
    String bookTitle = chapter.getBookTitle();
    String bookAuthor = chapter.getBookAuthor();
    String chapterTitle = chapter.getChapterTitle();
    String bookImage = chapter.getBookImage();

    currentPosition = position;
    chaptersRecycler.scrollToPosition(currentPosition);
    playAudio(bookImage, url, bookTitle, bookAuthor, chapterTitle);
}


/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p>
 * See the Android Training lesson <a href=
 * "http://developer.android.com/training/basics/fragments/communicating.html"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnChapterSelectedListener {
    // TODO: Update argument type and name
    void onChapterSelected(Uri uri);
}

public void volleyImageLoader(String url){
    ImageLoader imageLoader = AppSingleton.getInstance(getContext()).getImageLoader();

    imageLoader.get(url, new ImageLoader.ImageListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
        }

        @Override
        public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
            if (response.getBitmap() != null) {
                bookImage.setImageBitmap(response.getBitmap());

            }
        }
    });
}

private void playAudio(String bookImage, String media, String bookTitle, String authur, String chapterTitle) {

    if (player != null) {
        player.stop(true);
        player.release();
        player = null;
    }

    initializePlayer(media);

    ((MainActivity) getActivity()).miniBookTitle.setText(bookTitle);
    ((MainActivity) getActivity()).miniBookAuthor.setText(authur);

    ((MainActivity) getActivity()).txtMediaBookTitle.setText(bookTitle);
    ((MainActivity) getActivity()).txtMediaBookAuthor.setText(authur);
    ((MainActivity) getActivity()).txtMediaBookChapter.setText(chapterTitle);

    MEDIA_PLAYING_STATE = 1;
    volleyImageLoader(bookImage, ((MainActivity) getActivity()).miniBookImage);

}

private void initializePlayer(String url) {
    if (player == null) {
        player = ExoPlayerFactory.newSimpleInstance(getContext(),
                new DefaultTrackSelector(), new DefaultLoadControl());
        player.addListener(this);
        playerNotificationManager.setPlayer(player);
        playerNotificationManager.setMediaSessionToken(mMediaSession.getSessionToken());

        player.setPlayWhenReady(playWhenReady);
        player.seekTo(currentWindow, playbackPosition);

        ((MainActivity) getActivity()).playerControlView.setPlayer(player);
        ((MainActivity) getActivity()).miniPlayerControlView.setPlayer(player);

        Uri uri = Uri.parse(url);
        MediaSource mediaSource = buildMediaSource(uri);
        player.prepare(mediaSource, true, false);
    }
}

private MediaSource buildMediaSource(Uri uri) {
    return new ExtractorMediaSource.Factory(
            new DefaultHttpDataSourceFactory("exoplayer-codelab")).
            createMediaSource(uri);
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if((playbackState == ExoPlayer.STATE_READY) && playWhenReady){
        mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING,
                player.getCurrentPosition(), 1f);
        Log.d("onPlayerStateChanged:", "PLAYING");
    } else if((playbackState == ExoPlayer.STATE_READY)){
        mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED,
                player.getCurrentPosition(), 1f);
        Log.d("onPlayerStateChanged:", "PAUSED");
    }
    mMediaSession.setPlaybackState(mStateBuilder.build());
}

private class DescriptionAdapter implements
        PlayerNotificationManager.MediaDescriptionAdapter {

    @Override
    public String getCurrentContentTitle(Player player) {
        Chapter chapter = chapters.get(currentPosition);
        return  chapter.getBookTitle();
    }

    @Nullable
    @Override
    public String getCurrentContentText(Player player) {
        Chapter chapter = chapters.get(currentPosition);
        return chapter.getChapterNumber() + ": " + chapter.getChapterTitle();
    }

    @Nullable
    @Override
    public Bitmap getCurrentLargeIcon(Player player,
                                      PlayerNotificationManager.BitmapCallback callback) {
        int window = player.getCurrentWindowIndex();
        Bitmap largeIcon = null;
        return largeIcon;
    }

    @Nullable
    @Override
    public PendingIntent createCurrentContentIntent(Player player) {
        int window = player.getCurrentWindowIndex();
        return null;//createPendingIntent(window);
    }
}

private void releasePlayer(){
    playerNotificationManager.setPlayer(null);
    player.stop();
    player.release();
    player = null;
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
}

public void volleyImageLoader(String url, final ImageView imageView){
    ImageLoader imageLoader = AppSingleton.getInstance(getContext()).getImageLoader();

    imageLoader.get(url, new ImageLoader.ImageListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("debugger", "Image Load Error: " + error.getMessage());
        }

        @Override
        public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
            if (response.getBitmap() != null) {
                imageView.setImageBitmap(response.getBitmap());
            }
        }
    });
}

@SuppressLint("NewApi")
private class mySessionCallback extends MediaSessionCompat.Callback {
    @Override
    public void onPlay() {
        super.onPlay();
        player.setPlayWhenReady(true);
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onSkipToPrevious() {
        super.onSkipToPrevious();
        activePosition -= 1;
        ((MainActivity) getActivity()).layoutManager.setInitialPrefetchItemCount(activePosition);
        Log.d("debuugger", "Media Position: " + player.getCurrentPosition());
    }

    @Override
    public void onSkipToNext() {
        super.onSkipToNext();
        activePosition += 1;
        ((MainActivity) getActivity()).layoutManager.setInitialPrefetchItemCount(activePosition);
        Log.d("debuugger", "Media Position: " + player.getCurrentPosition());
    }
}

}

然后我在 Launching the BookChapters Fragment 中使用的代码如下

MainActivity myActivity = (MainActivity) context;
            BookChapters myBookChaptersFragment = new BookChapters();
            myBookChaptersFragment.setArguments(bundle);
            myActivity.getSupportFragmentManager().beginTransaction().
                    replace(R.id.book_chapters_fragment_container, myBookChaptersFragment, "book_chapters")
                    .addToBackStack("book_chapters")
                    .commit();

标签: androidandroid-fragments

解决方案


推荐阅读