You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio开发猜球星APP在OPPO真机运行崩溃求助

问题排查与修复方案

核心崩溃原因:主线程被阻塞

你的代码在onCreate方法中直接调用了AsyncTask.execute().get(),这个方法会同步阻塞主线程,强制等待网络请求完成。Android系统对主线程阻塞有严格限制,尤其是OPPO这类定制化ROM,会直接判定应用无响应并终止进程。模拟器环境宽松,所以没触发崩溃。

修复步骤:

  1. 移除AsyncTask的.get()调用,改用回调机制
    不要在主线程等待异步任务结果,重写AsyncTask的onPostExecute方法,在网络请求完成后再处理HTML解析和初始化UI:
public class DownloadTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {
        // 原网络请求逻辑不变
        String result = "";
        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL(urls[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            InputStream in = urlConnection.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);
            int data = reader.read();
            while (data != -1) {
                char current = (char) data;
                result += current;
                data = reader.read();
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if (result == null) {
            Toast.makeText(MainActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show();
            return;
        }
        // 把原来onCreate里解析HTML、初始化列表、调用newQuestion的逻辑移到这里
        try {
            String[] splitResult = result.split("<div class=\"organism contentStream slide\" id=\"slide68\">");
            if (splitResult.length < 2) {
                Toast.makeText(MainActivity.this, "页面结构变更,解析失败", Toast.LENGTH_SHORT).show();
                return;
            }
            // 解析图片URL逻辑
            Pattern p = Pattern.compile("<img alt=(.*?)>");
            Matcher m = p.matcher(splitResult[1]);
            while (m.find()) {
                Pattern p2 = Pattern.compile("src=\"(.*?)\"");
                Matcher m2 = p2.matcher(m.group(1));
                while (m2.find()) {
                    footballerURLs.add(m2.group(1));
                }
            }
            // 解析球星名字逻辑
            Pattern p3 = Pattern.compile("<div class=\"organism contentStream slide\"(.*?)/h2>");
            Matcher m3 = p3.matcher(splitResult[1]);
            while (m3.find()) {
                Pattern p4 = Pattern.compile("<h2>(.*?)<");
                Matcher m4 = p4.matcher(Objects.requireNonNull(m3.group(1)));
                while (m4.find()) {
                    String footballerName = m4.group(1).trim();
                    footballerName = footballerName.replaceAll("[0-9]", "");
                    footballerName = footballerName.replaceAll("\\. ", "");
                    footballerNames.add(footballerName);
                }
            }
            if (!footballerNames.isEmpty()) {
                footballerNames.remove(1);
            }
            // 初始化完成后加载题目
            newQuestion();
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "初始化失败", Toast.LENGTH_SHORT).show();
        }
    }
}

然后在onCreate里启动异步任务即可,不要调用.get():

DownloadTask task = new DownloadTask();
task.execute("https://bleacherreport.com/articles/705591-the-100-best-soccer-players-of-all-time");
  1. 修复newQuestion中的主线程阻塞问题
    同样,newQuestion里的imageTask.execute(...).get()也会阻塞主线程,改用onPostExecute回调:
public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected Bitmap doInBackground(String... urls) {
        // 原图片下载逻辑不变
        try {
            URL url = new URL(urls[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream inputStream = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);
            return myBitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
    }
}

修改newQuestion方法,去掉.get():

public void newQuestion() {
    try {
        Random rand = new Random();
        if (footballerURLs.isEmpty() || footballerNames.isEmpty()) {
            Toast.makeText(this, "数据未加载完成", Toast.LENGTH_SHORT).show();
            return;
        }
        chosenPlayer = rand.nextInt(footballerURLs.size());
        ImageDownloader imageTask = new ImageDownloader();
        imageTask.execute(footballerURLs.get(chosenPlayer));

        locationOfCorrectAnswer = rand.nextInt(4);
        int incorrectAnswerLocation;
        for (int i = 0; i < 4; i++) {
            if (i == locationOfCorrectAnswer) {
                answers[i] = footballerNames.get(chosenPlayer);
            } else {
                incorrectAnswerLocation = rand.nextInt(footballerURLs.size());
                while (incorrectAnswerLocation == chosenPlayer) {
                    incorrectAnswerLocation = rand.nextInt(footballerURLs.size());
                }
                answers[i] = footballerNames.get(incorrectAnswerLocation);
            }
        }
        // 提前设置按钮文本,不用等图片加载
        button0.setText(answers[0]);
        button1.setText(answers[1]);
        button2.setText(answers[2]);
        button3.setText(answers[3]);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

其他潜在问题与优化

  1. HTML解析健壮性不足
    依赖固定的HTML节点拆分(split("<div class=\"organism contentStream slide\" id=\"slide68\">")),一旦网站结构变更,会导致splitResult[1]数组越界抛异常。建议:
  • 增加数组长度判断,避免下标越界
  • 改用更可靠的HTML解析库替代正则,减少解析失败概率
  1. 网络安全配置
    如果图片URL是HTTP明文链接,Android 9+默认禁止,需要在res/xml/network_security_config.xml中配置允许明文请求:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

然后在AndroidManifest.xml的<application>标签中添加:

android:networkSecurityConfig="@xml/network_security_config"
  1. 权限检查
    确保AndroidManifest.xml中添加了网络权限:
<uses-permission android:name="android.permission.INTERNET" />

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:17:55