ProgressDialog или ProgressBar забавят приложението, работещо под Android 4.1

Разработвам приложение за Android, в което използвам AsyncTask, за да получа информация от уеб услуга с помощта на JSON, която след това се зарежда в ListView. До тук всичко работи добре.

Използвах ProgressDialog, който се инициира в метода onPreExecute() и се отхвърля в метода onPostExecute(). В емулатора, изпълняващ 2.3.3 Android версия, цялото това действие отнема до 7/8 секунди. Тествах с реално устройство с версия 2.3.6 и приложението има същото поведение.

Въпреки това, когато използвам емулатор, изпълняващ 4.1 версия на Android, това действие отнема от 65 до 70 секунди. Когато премахна ProgressDialog, действието отнема 7/8 секунди и в двете версии на Android 2.3 и 4.1. Тествах всички тези сценарии много пъти.

Защо това се случва? Нямам истинско устройство с версия 4.1 на Android, за да го тествам, така че се чудя дали това е проблем с емулатора? Опитах се да използвам нормален кръг на лентата за прогрес, вместо ProgressDialog, но се случва същото, просто отнема твърде много време във версията на Android 4.1.

Някакви идеи коя може да е причината за това странно поведение? :С

Благодаря ти.

dmon и James McCracken тук е кодът от моята дейност, можете ли да ми помогнете с това, моля?

public class MainActivity extends Activity {
private TextView tvTitleList;
private ListView lvDataSearch;
private ProgressDialog dialog;
private long timeStart;
private String[] dataSearch;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvTitleList = (TextView) findViewById(R.id.tvTitleList);
    lvDataSearch = (ListView) findViewById(R.id.lvDataSearch);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

public class ProcessUpdateList extends AsyncTask<Integer, String, String[]> {
    @Override
    protected void onPreExecute() {
        timeStart = System.currentTimeMillis();
        System.out.println("pre execute");
        try {
            tvTitleList.setText("working....");
            dialog = ProgressDialog.show(MainActivity.this, "", "Loading. Please wait...", true);
        } catch (Exception e) {
            System.out.println("Error Async 1: " + e.getMessage());
        }
    }

    @Override
    protected String[] doInBackground(Integer... paramss) {
        try {
            System.out.println("Get Data");
            dataSearch = getDataSearch();
        } catch (Exception e) {
            System.out.println("Error Async 2: " + e.getMessage());
        }
        System.out.println("Return Data "
                + ((System.currentTimeMillis() - timeStart) / 1000));
        return dataSearch;
    }

    @Override
    protected void onPostExecute(String[] values) {
        try {
            System.out.println("Post Execute Data");
            tvTitleList.setText("done in " + ((System.currentTimeMillis() - timeStart) / 1000));
            updateViewList();
            dialog.dismiss();
        } catch (Exception e) {
            System.out.println("Error Async 3: " + e.getMessage());
        }
    }
}

public void eventUpdateList() {     
    ProcessUpdateList process = new ProcessUpdateList();
    try {
        process.execute();
    } catch (Exception e) {
        System.out.println("NEW ERROR 2: " + e.getMessage());
    }
}   

public String[] getDataSearch() {   
    try {
        String readTwitterFeed = readJSON2("http://search.twitter.com/search.json?q=hey");

        JSONObject jsonObject = new JSONObject(readTwitterFeed);
        JSONArray jsonArray = new JSONArray();

        jsonArray.put(jsonObject);
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String json = gson.toJson(jsonObject);

        JSONObject jsonObject2 = new JSONObject(json);
        JSONObject level1 = jsonObject2.getJSONObject("nameValuePairs");
        JSONObject level2 = level1.getJSONObject("results");
        JSONArray level3 = level2.getJSONArray("values");

        dataSearch = new String[level3.length()];                   
        System.out.println(level3.length()+" resultados encontrados.");;

        for(int i=0; i<level3.length(); i++) {
            dataSearch[i] = level3.getJSONObject(i).getJSONObject("nameValuePairs").getString("text");
        }           
    }
    catch(JSONException e) {
        System.out.println(e.getMessage());
    }       
    return dataSearch;      
}

public String readJSON2(String command) {
    JSONObject jObj = null;
    StringBuilder builder = new StringBuilder();
    HttpClient client = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(command);
    try {
        HttpResponse response = client.execute(httpGet);
        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();
        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(content));
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
            reader.close();
            jObj = new JSONObject(builder.toString());
        } else {
            System.out.println(MainActivity.class.toString() + " Failed to download file");
        }
    } catch (Exception e) {
        return null;
    }
    return builder.toString();
}

public void updateViewList() {
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, dataSearch);                 
    lvDataSearch.setAdapter(adapter);
}

public void clickBRefreshList(View v) {
    eventUpdateList();
}
}

person SnitramSD    schedule 19.12.2012    source източник
comment
Не мога да се сетя за причина това да се случи. Можете ли да публикувате регистрационни файлове?   -  person James McCracken    schedule 20.12.2012
comment
Има нещо подозрително тук, показването на какъвто и да е изглед изобщо не трябва да отнема време. Също така не е ясно дали имате предвид 0,875 секунди или 7 или 8 секунди. Ако имаш предвид 7 - 8, значи нещо ОПРЕДЕЛЕНО не е наред. Трябва да публикувате кода за вашата AsyncTask.   -  person dmon    schedule 20.12.2012


Отговори (1)


Мога да потвърдя същото поведение само в емулатора, тествайки на 4.1. На действителното ми устройство (Galaxy S3 - 4.1) това не се случва. Освен това изглежда, че се случва само с неопределени ленти за напредък. Не знам защо се случва това, но може би ще се почувствате по-добре, като знаете, че това се случва и на други. Извършвам почти същите действия като вас, свързвам се с уеб услуга, анализирам xml отговор, след което показвам анализирания отговор. За информация, използвам ProgressBar за функцията android:empty на ListView.

РЕДАКТИРАНЕ: Направих някои тестове

Тествах анализиране на xml файла и с ProgressBar в оформлението получих това:

Parse time: 94785 ms

И така, промених това

<ProgressBar
        android:id="@id/android:empty"
        style="@android:style/Widget.Holo.ProgressBar"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:layout_gravity="center_horizontal|center_vertical" 
        android:layout_weight="1"/>

до това

 <TextView 
        android:id="@id/android:empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Searching..."/>

и получих това Parse time: 2642 ms

Забележка: моите ProgressBar и ListView са в LinearLayout и всички анализи се извършват в AsyncTask. Всичко това е в емулатора. Наистина странно... Предполагам, че емулаторът всъщност не отделя нишките от потребителския интерфейс, така че въртенето на AsyncTask и ProgressBar се бори за цикли на процесора, докато в действителен телефон той работи по предназначение, защото не се емулира.

Редактиране: И така, след като гледах TaskManager на моя WinXP, емулаторът стартира със 7 работещи нишки. Стартирам приложението си, преминавам през няколко AsyncTask с помощта на AsyncTask.THREAD_POOL_EXECUTOR и броят на нишките никога не се променя от 7 (в диспечера на задачите) по време на целия този процес.

person Matt    schedule 15.02.2013
comment
Тъкмо щях да пиша за подобен проблем, когато видях тази тема. Виждам същото в моя емулатор 4.4.2. AsyncTask, в който се обаждам и получавам отговор от http публикация, се увеличи от 1-2 секунди на 80-90 секунди само когато добавя прогресивна лента към изгледа. Не се появи с BlueStacks, работещ на Windows, така че препоръчвам на други хора също да тестват BlueStacks, ако нямат устройство с Android, с което да тестват. - person ScottyB; 24.08.2014