Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Rainmaker93
3 / 3 / 1
Регистрация: 12.09.2013
Сообщений: 69
#1

Async Task тормозит UI и не выводит диалог - Программирование Android

08.11.2015, 22:33. Просмотров 313. Ответов 5
Метки нет (Все метки)

Доброго времени суток, друзья.
Начитался про AsyncTask и решил запихнуть дерганье данных с сервера в поток.
Данные с сервера тянутся, записываются, но вот не отображается ProgressDialog и UI фризится на время выполнения задачи.
Подскажите пожалуйста, в чем проблема
Вот мой классик
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.helper.moto.motohelper;
 
 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
 
 
 
class ServerMarkerDownloader extends AsyncTask<Void,Void,ArrayList<MyMarker>> {
    public String SERVER_ADRESS;
    public String str="";
    public static final int CONNECTION_TIMEOUT =1000 * 15;
    public GoogleMap map;
    public Context context;
    ProgressDialog processing;
    
    
    public ServerMarkerDownloader(Context c, GoogleMap m){
        this.context=c;
        this.map = m; 
        readFile(c);        
    }
    
   
 
    @Override
    protected ArrayList<MyMarker> doInBackground(Void... params) {  
        
                
        HttpParams params1 = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params1, CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(params1, CONNECTION_TIMEOUT);
        
        HttpClient client = new DefaultHttpClient(params1);
        HttpPost post = new HttpPost(SERVER_ADRESS + "select_all_markers.php");
        
        
        ArrayList<MyMarker> serverMarkers = new ArrayList<MyMarker>();
        
        try
        {   
            
            HttpResponse httpResponse = client.execute(post);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);           
            String[] messages;
            messages = result.split("@");                                           
            for (int i = 0; i<messages.length;i++)
            {
                JSONObject jObject = new JSONObject(messages[i]);
                String jId = jObject.getString("id");
                String jlat = jObject.getString("lat");
                String jlon = jObject.getString("lng");
                String jtype = jObject.getString("type");
                String jdescr = jObject.getString("descr");
                String jtitle = jObject.getString("title");
                String juname = jObject.getString("username");
                String jphone = jObject.getString("phone");
                LatLng position = new LatLng(Double.valueOf(jlat),Double.valueOf(jlon));
                
                MyMarker markerToAdd = new MyMarker();
                markerToAdd.con = context;
                markerToAdd.internalID = jId;
                markerToAdd.position = position;
                markerToAdd.markerType = Integer.valueOf(jtype);
                markerToAdd.title = jtitle;
                markerToAdd.longDesc = jdescr;
                markerToAdd.map = map;
                markerToAdd.phone = jphone;
                markerToAdd.userName = juname;
                serverMarkers.add(i, markerToAdd);
                                        
            }       
            
        }           
            
        catch (Exception e)
        {
            e.printStackTrace();                        
        }
        return serverMarkers;
        }
 
        
    
        
    
    @Override
    protected void onPostExecute(ArrayList<MyMarker> result){
        processing.dismiss();
        super.onPostExecute(result);        
    }
    
    @Override
    protected void onPreExecute(){
         processing = new ProgressDialog(context);
         processing.setMessage("Выполнение");
         processing.setProgressStyle(ProgressDialog.STYLE_SPINNER);
         processing.setIndeterminate(true);
         processing.setCancelable(false);
         processing.show();
         processing.show();
        super.onPreExecute();
    }
     void readFile(Context context) {
         try {
              
              BufferedReader br = new BufferedReader(new InputStreamReader(
                  context.openFileInput("data.txt")));
 
              while ((str = br.readLine()) != null) {
                  SERVER_ADRESS=str;
              }
            } catch (FileNotFoundException e) {
              e.printStackTrace();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
 
}
а запускаю я его вот так
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void requestMarkersFromServer()
    {
        map.clear();
        markersFromServer = new ArrayList<MyMarker>();
        smd = new ServerMarkerDownloader(this, map);
        try {
            smd.execute();
            markersFromServer=smd.get();
            for(int i = 0; i<markersFromServer.size(); i++)
            {
                try{
                markersFromServer.get(i).recalculate();
                markersFromServer.get(i).addMarker();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        markersCollection.clear();
       
        for (int i=0; i< markersFromServer.size();++i)
        {
            markersCollection.put(markersFromServer.get(i).marker.getId(), markersFromServer.get(i));
        }
     
    }
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.11.2015, 22:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Async Task тормозит UI и не выводит диалог (Программирование Android):

Отмена async Task - C#
Хочу: 1) запускать асинхронный метод = ok 2) выводить в textbox процесс работы = ok 3) ждать завершения работы = ok 4) после...

.NET 4.x Task.Wait async Метод - C#
Всем привет. Нужна помощь. Я в сеттере (нужно именно тут) создаю таск Task task = new Task(Load); Сам лоад асинхронный: private...

.NET 4.x Многопоточность с async/await и Task - C#
Помогите разобраться с многопоточностью, совсем запутался после чтения множества статей. Нужно использовать async/await или таски. ...

.NET 4.x Потоки, мультипоточность Task or Async/Await or ThreadPool? - C#
Здравствуйте форумчане. Я очень нуждаюсь в вашей помощи. Я реализовываю парсер с одного довольно популярного сайта занятости и...

Как запустить private async Task SetInitialDataAsync сразу после запуска сайта из Global.asax ? - C# MVC
//запускается при попытке зарегистрироваться private async Task SetInitialDataAsync() { await...

Task.Factory.StartNew выводит одинаковые числа - C#
for (int i = 0; i &lt;= 20; i++) { Task.Factory.StartNew(()=&gt;Console.WriteLine(i)); } выводит...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
YuraAAA
1574 / 1316 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
08.11.2015, 23:27 #2
Rainmaker93, так как Вы написали sms.get ();
Данные надо возвращать через callback
1
Rainmaker93
3 / 3 / 1
Регистрация: 12.09.2013
Сообщений: 69
09.11.2015, 07:46  [ТС] #3
Цитата Сообщение от YuraAAA Посмотреть сообщение
Данные надо возвращать через callback
Будьте добры, приведите пример пожалуйста.
Не очень понимаю о чем идет речь

Добавлено через 8 часов 9 минут
YuraAAA, Спасибо за подсказку про callback'и. Сделал с помощью слушателей
Не могли бы Вы подсказать еще, можно ли вызывать этот поток постоянно через интервал?
если можно, то дайте пожалуйста ссылку или покажите пример.
0
bastrakov
91 / 91 / 14
Регистрация: 10.10.2015
Сообщений: 307
Записей в блоге: 1
09.11.2015, 10:07 #4
повтор через интервал делается примерно так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  Handler handler = new Handler();
  
handler.post(runnableCode);
 
  private Runnable runnableCode = new Runnable()
  {
    @Override
    public void run()
    {
        doSomeHere();
        handler.postDelayed(runnableCode, 5000); //5sec
      }
    }
  };
0
YuraAAA
1574 / 1316 / 271
Регистрация: 25.10.2009
Сообщений: 3,438
Записей в блоге: 2
09.11.2015, 11:49 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Rainmaker93, добавляем колбэк.
1. Пишем интерфейс обратного вызова:

Java
1
2
3
4
5
6
7
public interface IMarkerCallback {
 
    void onSuccess(ArrayList<MyMarker> markers);
 
    void onFailure(Throwable throwable);
 
}
2. Добавляем 2 поля в asynctask:

Java
1
2
private IMarkerCallback callback;
private Throwable t;
3. Колбэк добавляем в конструктор третьим параметром:

Java
1
2
3
4
5
6
public ServerMarkerDownloader(Context c, GoogleMap m, IMarkerCallback markerCallback) {
        this.context = c;
        this.map = m;
        this.callback = callback;
        readFile(c);
    }
4. Модифицируем try-catch, а именно catch блок

Java
1
2
3
} catch (Exception e) {
            this.t = e;
        }
5. Модифицируем onPostExecute:

Java
1
2
3
4
5
6
7
@Override
    protected void onPostExecute(ArrayList<MyMarker> result) {
        processing.dismiss();
        super.onPostExecute(result);
        if (t != null) callback.onFailure(t);
        else callback.onSuccess(result);
    }
6. Вызов:

Java
1
2
3
4
5
6
7
8
9
10
11
ServerMarkerDownloader serverMarkerDownloader = new ServerMarkerDownloader(this, map, new IMarkerCallback() {
            @Override
            public void onSuccess(ArrayList<MyMarker> markers) {
                //Ok!
            }
 
            @Override
            public void onFailure(Throwable throwable) {
                //Oops, something goes wrong
            }
        });
Добавлено через 1 минуту
Цитата Сообщение от Rainmaker93 Посмотреть сообщение
Не могли бы Вы подсказать еще, можно ли вызывать этот поток постоянно через интервал?
Посмотрите в сторону Timer + TimerTask
1
Rainmaker93
3 / 3 / 1
Регистрация: 12.09.2013
Сообщений: 69
09.11.2015, 22:25  [ТС] #6
YuraAAA,
Огромное Вам спасибо за подробные разъяснения
все работает!

С таймером поступил так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void getMarkersByTimer(int milsec)
    {
     final Handler handler;
     handler = new Handler();
     Timer  timer = new Timer();
     TimerTask doAsynchronousTask = new TimerTask()
     {       
         @Override
         public void run() {
             handler.post(new Runnable() {
                 public void run() {       
                     try
                     {
                         MapActivity.this.runOnUiThread( new Runnable()
                         {  
                             @Override
                             public void run() {
                                // TODO Auto-generated method stub
                             markerRefresher = new MarkerRefresher(MapActivity.this, map);
                             markerRefresher.setOnRefreshed(MapActivity.this);
                             markerRefresher.execute();
                            }
                             
                         }
                         );
                     } 
                     catch (Exception e) 
                     {
 
                     }
                 }
             });
         }
     };
     timer.schedule(doAsynchronousTask, 0, milsec);
    
    }
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2015, 22:25
Привет! Вот еще темы с ответами:

Как корректно заменить async: false на async: true - JavaScript
Проблема в том, что данный код устарел, блокирует браузер на время выполнения скрипта и выдает warning: Synchronous XMLHttpRequest on...

[UWP] Возвращаемым типом асинхронного метода должен быть void, Task или Task<T> - C# WPF
Создал асинхронный метод. Он должен на выходе вывести объект который состоит из строк. Пишет ошибка, что можно сделать? Первый скрин с...

Отмена одного Task в массиве Task - C#
Как можно отменить одну задачу в массиве Task? Никак же нельзя передать CancellationTokenSource в массиве?

Async Free (СОМ-порт)-Async Pro (СОМ-порт)? - Delphi
Здравствуйте! Скажите пожалуйста есть пример где используют Async Free (СОМ-порт) или Async Pro (СОМ-порт)? почему то не могу найти и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.11.2015, 22:25
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru