Java 应用程序在使用AsyncTask时挂起和挂起所有线程

Java 应用程序在使用AsyncTask时挂起和挂起所有线程,java,android,multithreading,Java,Android,Multithreading,我正在尝试使用AsyncTask类来获取网站的内容。logcat告诉我W/art:Suspending所有线程需要:15(或任何其他数字)ms。我的应用程序被冻结,直到日志消息打印完毕。完成日志后将显示UI。我遵循了一个教程,并仔细检查了我的代码是否与教程相同。一段时间后,它从网站上记录了几行代码,但仅此而已。我也尝试了不同的网站。以下是我的任务: public class MainActivity extends AppCompatActivity { public class Do

我正在尝试使用
AsyncTask
类来获取网站的内容。logcat告诉我
W/art:Suspending所有线程需要:15(或任何其他数字)ms
。我的应用程序被冻结,直到日志消息打印完毕。完成日志后将显示UI。我遵循了一个教程,并仔细检查了我的代码是否与教程相同。一段时间后,它从网站上记录了几行代码,但仅此而已。我也尝试了不同的网站。以下是我的任务:

public class MainActivity extends AppCompatActivity {

    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 onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        String result = null;

        try {

            result = task.execute("http://www.vg.no/").get();

            Log.i("URL content" , result);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

    }


}
public class MainActivity extends AppCompatActivity {

   public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            ...
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i("URL content" , result);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        task.execute("http://www.vg.no/");
    }


}
public类MainActivity扩展了AppCompatActivity{
公共类DownloadTask扩展了AsyncTask{
@凌驾
受保护的字符串doInBackground(字符串…URL){
字符串结果=”;
网址;
HttpURLConnection-urlConnection=null;
试一试{
url=新url(url[0]);
urlConnection=(HttpURLConnection)url.openConnection();
InputStream in=urlConnection.getInputStream();
InputStreamReader reader=新的InputStreamReader(in);
int data=reader.read();
while(数据!=-1){
当前字符=(字符)数据;
结果+=电流;
data=reader.read();
}
返回结果;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar Toolbar=(Toolbar)findViewById(R.id.Toolbar);
设置支持操作栏(工具栏);
DownloadTask任务=新建DownloadTask();
字符串结果=null;
试一试{
结果=任务。执行(“http://www.vg.no/).get();
Log.i(“URL内容”,结果);
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
}
}

以下行是一个问题:

result=task.execute(“http://www.vg.no/).get()

此语句的
.get()
部分表示“等待任务完成”。这有效地阻止了任务执行时的UI线程

只需让后台任务完成它的工作,并通过
onPostExecute()
返回任何结果即可。检查以下异步任务:

public class MainActivity extends AppCompatActivity {

    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 onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        String result = null;

        try {

            result = task.execute("http://www.vg.no/").get();

            Log.i("URL content" , result);

        } catch (InterruptedException e) {

            e.printStackTrace();

        } catch (ExecutionException e) {

            e.printStackTrace();

        }

    }


}
public class MainActivity extends AppCompatActivity {

   public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {
            ...
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i("URL content" , result);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DownloadTask task = new DownloadTask();
        task.execute("http://www.vg.no/");
    }


}
public类MainActivity扩展了AppCompatActivity{
公共类DownloadTask扩展了AsyncTask{
@凌驾
受保护的字符串doInBackground(字符串…URL){
...
}
@凌驾
受保护的void onPostExecute(字符串结果){
Log.i(“URL内容”,结果);
}
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar Toolbar=(Toolbar)findViewById(R.id.Toolbar);
设置支持操作栏(工具栏);
DownloadTask任务=新建DownloadTask();
任务。执行(“http://www.vg.no/");
}
}

首先,我认为你误用了异步任务。异步任务应异步使用,而不是使用get()同步使用

您应该在AsyncTask中添加onPostExecute并在那里获得结果

protected void onPostExecute(String result) {
     //You could get the result here
}
您可以在此处阅读更好的教程->

我也遇到了同样的问题。“while”是你问题的原因,你需要摆脱它

我正在尝试使用AsyncTask类来获取网站的内容。logcat告诉我W/art:暂停所有线程需要:15(或任何其他数字)毫秒重复。

你有更好的选择

从“线程性能””文章作者:

使用AsyncTask时,需要记住几个重要的性能方面。首先,默认情况下,应用程序将其创建的所有AsyncTask对象推送到单个线程中。因此,它们以串行方式执行,与主线程一样,一个特别长的工作包可以阻塞队列。因此,我们建议您仅使用AsyncTask来处理持续时间小于5ms的工作项。

您可以使用它作为替代方案。如果您有许多URL要获取,请选择

查看相关帖子:


这修复了应用程序冻结的问题,但我仍然在日志中收到所有“W/art:Suspending all threads take:9.850ms”消息。我还发现:“I/art:Background partial concurrent mark sweep GC释放了58个(2048B)AllocSpace对象,45个(16MB)LOS对象,40%空闲,21MB/36MB,暂停7.230ms总计23.895ms”@EmilØgård这些消息对所有应用程序来说都是常见的,你不应该担心。它们只是Android框架日志记录的一部分,用于诊断内存管理问题和调试问题。在几乎所有的应用程序中,它们都可以被安全地忽略(而且你无法摆脱它们)。更具体地说,“标记扫描GC”就是报告垃圾收集器正在回收内存。“挂起所有线程”消息是因为当垃圾收集器执行其工作时,必须挂起所有线程。这一特殊的扫描耗时约24毫秒,或眨眼的十分之一好的,谢谢。但为什么我输入的网站只输出了3行?这发生在数十条日志消息之后。@EmilØgård可能是因为您试图记录太多的数据。logcat中的日志设计用于打印短消息,如果消息太长,则只需剪切消息即可。我下载了你正在使用的网站:输出超过380K,第四行超过13000个字符-这是一个疯狂的数字,试图在系统日志中打印。只需将输出保存到一个文件中,或将其加载到TextView中即可。