You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

安卓应用进入飞行模式后崩溃问题求助(附MoviesListFragment代码)

解决飞行模式下电影列表加载崩溃的问题

嘿,我看了你遇到的问题——开启飞行模式后加载电影列表时应用崩溃了,结合你提供的MoviesListFragment.java代码,我来帮你定位问题并给出具体的修复方案。

核心问题分析

从代码逻辑来看,崩溃的主要原因是没有处理无网络场景下的异常

  • 飞行模式下没有网络连接,当loadCards()发起网络请求时,会触发网络相关异常(比如IOException),如果你的异步任务(用来拉取电影数据的)没有捕获这些异常,就会直接导致应用崩溃。
  • 另外,当前代码里的错误状态处理不够完善,无网络时可能会出现空指针或数据加载失败后的非法操作。

具体修复步骤

1. 给网络请求添加异常捕获

假设你的loadCards()方法是通过异步任务(比如FetchMoviesTask)发起网络请求,一定要在doInBackground里捕获所有可能的异常,并在onPostExecute里正确处理结果:

private class FetchMoviesTask extends AsyncTask<Integer, Void, List<Movie>> {
    @Override
    protected List<Movie> doInBackground(Integer... params) {
        if (params.length == 0) {
            return null;
        }
        int sorting = params[0];
        try {
            // 这里替换成你实际的网络请求和数据解析逻辑
            return MovieApiUtils.fetchMovies(sorting, mPage);
        } catch (IOException e) {
            Log.e(TAG, "网络请求失败: ", e);
            return null;
        } catch (JSONException e) {
            Log.e(TAG, "数据解析失败: ", e);
            return null;
        }
    }

    @Override
    protected void onPostExecute(List<Movie> movies) {
        // 隐藏加载指示器和下拉刷新状态
        mLoadingIndicator.setVisibility(View.INVISIBLE);
        mSwipeContainer.setRefreshing(false);
        
        if (movies != null && !movies.isEmpty()) {
            // 有数据就添加到适配器(支持分页加载)
            mMoviesAdapter.addMoviesData(movies);
            mErrorMessageDisplay.setVisibility(View.INVISIBLE);
        } else {
            // 无数据时显示友好错误提示
            mErrorMessageDisplay.setText(R.string.error_no_network);
            mErrorMessageDisplay.setVisibility(View.VISIBLE);
            clearGridView();
        }
    }
}

2. 提前检查网络状态

在发起网络请求前先判断设备是否有网络,避免无效请求并提前给出提示:

private void loadCards(int sorting) {
    // 获取网络连接管理器
    ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

    if (!isConnected) {
        // 无网络时直接显示错误
        mLoadingIndicator.setVisibility(View.INVISIBLE);
        mSwipeContainer.setRefreshing(false);
        mErrorMessageDisplay.setText(R.string.error_no_network);
        mErrorMessageDisplay.setVisibility(View.VISIBLE);
        return;
    }

    // 有网络才发起请求
    mLoadingIndicator.setVisibility(View.VISIBLE);
    new FetchMoviesTask().execute(sorting);
}

别忘了在AndroidManifest.xml里添加必要的权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

3. 确保适配器的空数据安全

你的PosterAdapter要能处理空数据的情况,避免因数据为空导致的崩溃:

public class PosterAdapter extends RecyclerView.Adapter<PosterAdapter.PosterViewHolder> {
    private List<Movie> mMoviesData;

    // ... 其他已有代码

    @Override
    public int getItemCount() {
        // 数据为空时返回0,避免NullPointerException
        return mMoviesData == null ? 0 : mMoviesData.size();
    }

    // 替换原有的setMoviesData,增加空判断
    public void setMoviesData(List<Movie> moviesData) {
        mMoviesData = moviesData;
        notifyDataSetChanged();
    }

    // 新增add方法,支持分页加载时追加数据
    public void addMoviesData(List<Movie> moviesData) {
        if (mMoviesData == null) {
            mMoviesData = new ArrayList<>();
        }
        mMoviesData.addAll(moviesData);
        notifyDataSetChanged();
    }
}

4. 完善错误状态的恢复逻辑

onCreateView里,要正确恢复之前保存的错误状态:

Boolean errorShown = false;
if (savedInstanceState != null){
    errorShown = savedInstanceState.getBoolean(BUNDLE_ERROR_KEY);
    if (errorShown) {
        mErrorMessageDisplay.setVisibility(View.VISIBLE);
        mErrorMessageDisplay.setText(R.string.error_no_network);
    }
}

总结

这些修改主要是从异常捕获、网络检查、数据安全、状态恢复四个方面入手,确保在飞行模式(无网络)下,应用不会崩溃,而是友好地显示错误提示,提升用户体验。

内容的提问来源于stack exchange,提问作者kaizen

火山引擎 最新活动