Многопоточное приложение Android сбоит - PullRequest
0 голосов
/ 11 февраля 2011

Моя программа структурирована следующим образом.У меня есть следующий основной вид деятельности.Это действие создаст объект «Определить местоположение».Этот объект определения местоположения будет принимать несколько параметров.Среди них есть обработчик для передачи результатов.В следующем я перехожу в threadHandler, который имеет тип MyThreadHandler (расширение обработчика).Этот объект DetermineLocation реализует runnable, а в методе run он запрашивает GPS и передает результаты в сообщении threadHandler (переданному в объект DetLoc).Экземпляр threadHandler принимает объект textview при создании (это текстовое представление для обновления)

В целях отладки я отключил функцию обновления GPS и только метод запуска DetLoc передавал случайное число.Это, тем не менее, все еще приводит к сбою моей программы.

Сбой в основном происходит при одновременной передаче большого количества данных на устройство (например, быстрое нажатие на экран в нескольких местах).Это проблема с потоком, но я не понимаю, почему.

MAIN:

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    threadModifiedText = (TextView) findViewById(R.id.thread_modified_text);

    threadHandler = new MyHandler(threadModifiedText);

    //Start up the DetermineLocation thread.  This thread will query the GPS every N milliseconds.
    // then push the results over hte network if at all possible
    DetermineLocation detLoc = new DetermineLocation(this, threadHandler, 3000);
    Thread detLocThread = new Thread(detLoc);
    detLocThread.start();
}

ТАКЖЕ MAIN:

class MyHandler extends Handler{

private TextView threadModifiedText;
public MyHandler(TextView tv) {
    threadModifiedText = tv;
}

 public void handleMessage(Message msg) {
        // whenever the Thread notifies this handler we have
        // only this behavior
        threadModifiedText.setText((CharSequence)msg.obj);
 }
}

Определить класс местоположения (как вы можете видетьматериал GPS закомментирован и все еще падает):

public class DetermineLocation implements Runnable {
private int updateInterval;
private int provider=3;
private Handler threadHandler;
private Context c;

public final int GPS_ONLY=1;
public final int NETWORK_ONLY=2;
public final int ANY_AVAILABLE=3;

public DetermineLocation(Context c, Handler h, int ui) {
    this.c = c;
    this.updateInterval = ui;
    this.threadHandler = h;

}

public void changeProvider(int providerConst) { 
    if(providerConst <=3 && providerConst >= 1)
        provider = providerConst;
}

public void changeUpdateInterval(int updateIntervalMS) {
    if(updateIntervalMS >= 0)
        this.updateInterval = updateIntervalMS;
}

@Override
public void run() {
    Message m = new Message();
    //LocationManager locationManager = (LocationManager)c.getSystemService(Context.LOCATION_SERVICE); 
    //Location loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    while(true) {

    CharSequence cs = Math.random() + "\r\n"; //+ loc.getLatitude() + " " + loc.getLongitude();
    m.obj = cs;
    threadHandler.sendMessage(m);

    try {
        Thread.sleep(updateInterval);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    }

}

1 Ответ

3 голосов
/ 12 февраля 2011

Вы, похоже, создаете экземпляр только одного Message, непрерывно записываете его в фоновый поток, а затем непрерывно читаете его из потока пользовательского интерфейса без синхронизации. Не удивительно, что дела идут бум.

Вы можете исправить это, используя Message.obtain() для каждого сообщения, которое вы отправляете через границу потока, или вы можете значительно упростить свою жизнь, используя AsyncTask.

С AsyncTask вам не нужны Handlers или Runnables ... это делает работу с потоками настолько простой, насколько это должно быть.

...