即使在使用ASyncTask之后,应用程序也可能在其主线程上做了太多工作

时间:2017-11-19 07:45:35

标签: java android json multithreading android-asynctask

所以我是Android开发的新手,我刚刚学习了ASyncTask。我正在我的一个应用程序中使用它,但我仍然收到警告:“应用程序可能在其主线程上做了太多工作”并且它也在跳帧。

我正在从我的网站解析一个json文本,该文本从数据库中提取数据并将其转换为json。

TextView t1;
TextView t2;
TextView t3;
EditText editText;

public boolean checkNumber(String n){
    boolean flag=true;
    for(int i=0;i<n.length();i++){
        char ch=n.charAt(i);
        if(!(Character.isDigit(ch))){
            flag=false;
            break;
        }
    }
    return flag;
}

public static class getContent extends AsyncTask<String, Void, String>{

    @Override
    protected String doInBackground(String... urls) {
        String r="";
        URL url;
        HttpURLConnection httpURLConnection;

        try {

            url=new URL(urls[0]);
            httpURLConnection= (HttpURLConnection) url.openConnection();

            InputStream in=httpURLConnection.getInputStream();
            InputStreamReader reader=new InputStreamReader(in);

            int data=reader.read();

            while(data != -1){
                char ch=(char) data;
                r=r+ch;
                data=reader.read();
            }

            return r;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

public void findUser(View view) throws ExecutionException, InterruptedException, JSONException {
    t1=findViewById(R.id.nameView);
    t2=findViewById(R.id.emailView);
    t3=findViewById(R.id.countryView);
    editText=findViewById(R.id.numberEditText);

    String s=editText.getText().toString();

    if((s.length()==0) || (!checkNumber(s))){
        Toast.makeText(this, "Please enter a number...", Toast.LENGTH_SHORT).show();
    }else{
        getContent getContent=new getContent();
        String json=getContent.execute("http://www.website.com/Test/index.php?id="+s).get();

        JSONObject jsonObject=new JSONObject(json);
        String error=jsonObject.getString("error");
        if(error.equals("false")){
            String name=jsonObject.getString("name");
            String email=jsonObject.getString("email");
            String country=jsonObject.getString("country");

            t1.setText("Name: "+name);
            t2.setText("Email: "+email);
            t3.setText("Country: "+country);
        }else{
            Toast.makeText(this, "Cannot Find a user...", Toast.LENGTH_SHORT).show();
        }

    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="net.vishurules.jsondata.MainActivity">

    <EditText
        android:id="@+id/numberEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="58dp"
        android:ems="10"
        android:hint="@string/pick_a_number"
        android:inputType="number" />

    <Button
        android:id="@+id/goButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/numberEditText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:onClick="findUser"
        android:text="@string/go" />

    <TextView
        android:id="@+id/nameView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/goButton"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="125dp"
        android:text="@string/name"
        android:textSize="32sp" />

    <TextView
        android:id="@+id/emailView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/nameView"
        android:layout_below="@+id/nameView"
        android:layout_marginTop="15dp"
        android:text="@string/email"
        android:textSize="32sp" />

    <TextView
        android:id="@+id/countryView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/emailView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:text="@string/country"
        android:textSize="32sp" />
</RelativeLayout>

2 个答案:

答案 0 :(得分:1)

AsyncTask的目的是在主线程之外做一些工作而不阻塞它,并在AsyncTask上调用 .get()

getContent.execute("http://www.website.com/Test/index.php?id="+s).get();

您正在阻止主线程,直到AsyncTask完成。

尝试通过覆盖AsyncTask(适用于主线程)的onPostExecute(Result result)函数将结果从AsyncTask传递到UI。

来自google的示例:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {
     int count = urls.length;
     long totalSize = 0;
     for (int i = 0; i < count; i++) {
         totalSize += Downloader.downloadFile(urls[i]);
         publishProgress((int) ((i / (float) count) * 100));
         // Escape early if cancel() is called
         if (isCancelled()) break;
     }
     return totalSize;
 }

 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute(Long result) {
     showDialog("Downloaded " + result + " bytes");
 }
}

答案 1 :(得分:-1)

正如它所述,应用程序在其主线程上做了太多工作,这意味着在主线程上会有更多的工作。

如果正在跳过的帧数大于100,则意味着它不是一个大问题。目前您可能正在使用模拟器测试应用程序。但是如果帧数超过这个数量,那意味着您需要在应用中使用更多线程。

您可以在此处使用runOnUiThread来更新TextView,如下所示:

if(error.equals("false")){
     private void runThread(){
     runOnUiThread (new Thread(new Runnable() { 
         public void run() {
            String name=jsonObject.getString("name");
            String email=jsonObject.getString("email");
            String country=jsonObject.getString("country");

            t1.setText("Name: "+name);
            t2.setText("Email: "+email);
            t3.setText("Country: "+country);
         }
     }));
}

我希望有帮助