Android Fragment+ViewModel项目获取站点HTML启动即最小化闪退问题求助
问题原因与解决方法
核心错误原因
- 未声明网络权限:报错日志明确提示
SecurityException: Permission denied (missing INTERNET permission?),Android系统默认禁止应用访问网络,必须主动声明权限才可以执行网络请求。 - AsyncTask使用逻辑错误:AsyncTask是异步执行任务,你在调用
execute()之后直接将DownLoad实例转成字符串,拿到的只是类实例的默认toString结果,根本不是网络请求返回的HTML内容,同时也缺少请求完成后更新UI的逻辑。 - 未用到ViewModel能力:你当前创建了ViewModel但完全没有使用,异步请求的结果应该存储在ViewModel中,避免页面重建(比如横竖屏切换)时重复请求或者数据丢失。
具体解决步骤
1. 添加网络权限
打开项目的app/src/main/AndroidManifest.xml,在<manifest>标签下(<application>标签外层)添加以下权限声明:
<uses-permission android:name="android.permission.INTERNET" />
如果你的应用targetSdkVersion >= 28且后续需要访问HTTP站点,还需要在<application>标签中添加android:usesCleartextTraffic="true"配置。
2. 修正代码逻辑对接ViewModel
首先修改MainViewModel类,添加存储HTML内容的LiveData:
public class MainViewModel extends ViewModel { private MutableLiveData<String> htmlContent = new MutableLiveData<>(); public LiveData<String> getHtmlContent() { return htmlContent; } public void setHtmlContent(String content) { htmlContent.postValue(content); } }
然后修改MainFragment代码,补充AsyncTask结果回调、UI更新逻辑:
public class MainFragment extends Fragment{ final public String URL_POSTER = "https://udmfil.ru/"; private MainViewModel viewModel; private TextView contentTv; // 对应布局中用来显示HTML内容的TextView public static MainFragment newInstance() { return new MainFragment(); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // 先绑定布局和控件 View root = inflater.inflate(R.layout.main_fragment, container, false); contentTv = root.findViewById(R.id.your_textview_id); // 替换为你布局里TextView的实际id // 初始化ViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class); // 监听HTML内容变化,自动更新UI viewModel.getHtmlContent().observe(getViewLifecycleOwner(), html -> { if (html != null) { contentTv.setText(html); } }); // 启动网络请求 new DownLoad().execute(URL_POSTER); return root; } public class DownLoad extends AsyncTask<String,Void,String> { @Override protected String doInBackground(String... strings) { HttpURLConnection connection = null; BufferedReader reader= null; StringBuilder buffer = new StringBuilder(); try { URL url = new URL(strings[0]); connection = (HttpURLConnection) url.openConnection(); connection.connect(); InputStream stream = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(stream)); String line; while ((line = reader.readLine()) != null) { buffer.append(line); } } catch (IOException e) { e.printStackTrace(); return null; } finally { if (connection != null) connection.disconnect(); try { if (reader != null) reader.close(); }catch (IOException e){ e.printStackTrace(); } } return buffer.toString(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); // 异步任务结束后把结果传给ViewModel if (s != null) { viewModel.setHtmlContent(s); } } } }
补充说明
AsyncTask已经在Android 11中被正式废弃,正式项目更推荐使用OkHttp、Retrofit等成熟网络框架,配合协程或者RxJava处理异步逻辑。
内容的提问来源于stack exchange,提问作者Сергей Дёшин
相关产品推荐
相关产品推荐

