从 Android 中的 Async 类调用 Async 类不起作用?

Posted

技术标签:

【中文标题】从 Android 中的 Async 类调用 Async 类不起作用?【英文标题】:Calling Async class from Async class in Android not working? 【发布时间】:2018-12-30 08:20:57 【问题描述】:

所以我的目标是加载一个随机的***页面,从中获取标题,然后使用*** api 获取正确的标题以返回显示(带有特殊字符的标题需要“翻译”才能显示它们正确。)当我使用我的 JSONRequest 类(异步)尝试执行 api url 并创建一个 JSON 对象时,我的问题就来了。当它尝试执行时,它会冻结并且不会继续执行(但不会崩溃)。这不是 URL 的问题,它是有效的并且可以在桌面和移动设备上运行。这个方法也用在另一个非异步类中,所以我知道它在那里工作。我的猜测是这是一个异步问题。这可能是一个简单的答案的愚蠢问题,但非常感谢任何帮助!

    public class getRandom extends AsyncTask<String, Void, String> 
    private static final String REQUEST_METHOD = "GET";
    private static final int READ_TIMEOUT = 15000;
    private static final int CONNECTION_TIMEOUT = 15000;
    String result, rawTitle;

    // Gets random wiki page and returns text to be loaded into search bar
    @Override
    protected String doInBackground(String... params)
        String randomUrl = "https://en.wikipedia.org/wiki/Special:Random";
        String titleApiUrl = "https://en.wikipedia.org/w/api.php?action=query&format=json&titles=";

        // Get random title
        try 
            URL url = new URL(randomUrl);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            //Set method and timeouts
            con.setRequestMethod(REQUEST_METHOD);
            con.setReadTimeout(READ_TIMEOUT);
            con.setConnectTimeout(CONNECTION_TIMEOUT);

            // Get status
            int status = con.getResponseCode();

            // Check for move or redirect and update url
            if (status == HttpURLConnection.HTTP_MOVED_TEMP
                    || status == HttpURLConnection.HTTP_MOVED_PERM) 
                String location = con.getHeaderField("Location");
                URL newUrl = new URL(location);
                con = (HttpURLConnection) newUrl.openConnection();
            

            // Get name of page
            rawTitle = con.toString();
            int temp = rawTitle.indexOf("wiki/") + 5;
            rawTitle = rawTitle.substring(temp);

            con.disconnect();
        
        catch(IOException e)
            e.printStackTrace();
            rawTitle = "Sailboats"; // Very random, totally not hard coded result.
        

        // Ensure correct title format (use wiki api)
        try
            // Get json from api
            JSONRequest wikiRequest = new JSONRequest();
            String wikiApiJsonString = wikiRequest.execute(titleApiUrl + rawTitle).get();

            // Create json object with returned string
            JSONObject jsonObj = new JSONObject(wikiApiJsonString);

            // Get correct title from json
            result = jsonObj.getString("title");
        
        catch(ExecutionException | InterruptedException |  JSONException e)
            e.printStackTrace();
            result = "Sailboats"; // Very random, totally not hard coded result.
        

        return result;
    
    protected void onPostExecute(String result)
        super.onPostExecute(result);
    

【问题讨论】:

【参考方案1】:

默认情况下,异步任务都在同一个线程上运行。因此,在您完成之前,它实际上不会开始第二个任务。您的选择是:

1)调用executeOnExecutor而不是execute并告诉它使用一个新线程。

2) 设计您的代码,以便您可以直接在此线程上发出请求。你已经在一个线程上,没有理由发布一个新的。

3)编写你的代码,比如你不需要调用.get()。

【讨论】:

以上是关于从 Android 中的 Async 类调用 Async 类不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

阿里巴巴为什么不建议直接使用Async注解?

RN 调用安卓的原生方法(实现Toast效果)

如何从android中的非Activity类调用服务方法

android,异步任务类中的Toast如何获得Context?

Spring boot 注解@Async

Android 如何从 Main Activity 中的另一个类调用 Activity 数据类型?