简体   繁体   English

Android多线程应用程序崩溃

[英]Android Multithreaded Application is Crashing

My program is structured as followed. 我的程序结构如下。 I have the following main activity. 我有以下主要活动。 This activity will create a "Determine Location" object. 该活动将创建一个“确定位置”对象。 This Determine location object will take in a few parameters. 这个确定位置对象将包含一些参数。 Amongst them is a handler to pass the results along to. 其中包括一个将结果传递给的处理程序。 In the following I pass in threadHandler which is of type MyThreadHandler (an extension of handler). 在下面的代码中,我传入了类型为MyThreadHandler(处理程序的扩展)的threadHandler。 This DetermineLocation object implements runnable and in the run method it queries the GPS and passes the results along in a message to threadHandler (passed into the DetLoc object). 这个确定位置对象实现可运行,并在run方法中查询GPS,并将结果通过消息传递给threadHandler(传递给DetLoc对象)。 The threadHandler instance takes in a textview object upon creation (this is the text view to update) 创建时,threadHandler实例将接收一个textview对象(这是要更新的文本视图)

For debugging purposes I have disabled the GPS update feature and only had DetLoc's run method pass a random number. 出于调试目的,我禁用了GPS更新功能,仅让DetLoc的run方法传递了随机数。 This however is still crashing my program. 但是,这仍然使我的程序崩溃。

The crash mainly happens while pushing a lot of input to the device (such as pressing the screen in multiple places really fast). 崩溃主要发生在向设备推入大量输入时(例如非常快地在多个位置按下屏幕)。 This is a thread issue for sure but I do not see why. 这肯定是一个线程问题,但我不明白为什么。

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();
}

ALSO 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);
 }
}

DetermineLocation class (as you can see the GPS stuff has been commented out and its still crashing): 确定位置类(如您所见,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();
    }

    }

}

You appear to be instantiating just the one Message , writing it continuously on your background thread, and then reading it continuously from your UI thread, with no synchronization. 您似乎只实例化了一条Message ,将其连续写入后台线程,然后从UI线程连续读取,而没有同步。 It's not surprising things go boom. 事情兴隆并不奇怪。

You can fix this either by using Message.obtain() for each message you send across the thread boundary, or you can make your life a whole lot simpler by using an AsyncTask . 您可以通过对跨线程边界发送的每条消息使用Message.obtain()来解决此Message.obtain() ,也可以使用AsyncTask使生活变得更加简单。

With an AsyncTask you don't need any Handlers or Runnables ... it makes threading as simple as it ought to be. 使用AsyncTask您不需要任何HandlersRunnables ……它使线程变得应有的简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM