为什么我无法在我的Activity中启动2x线程?

时间:2011-05-28 16:44:45

标签: java android multithreading

我将我的活动中的Web服务调用推送到一个线程(如下所示)。我第一次在活动中这样做它工作正常(从我的edittext获取文本并加载服务以获取lat / lng数据)

但是,当我单击后退按钮(模拟器)并尝试在.start()之后第二次触发此线程时。在我的点击处理程序中我在这里做错了什么?感谢

private Thread getLocationByZip = new Thread() {
    public void run() {
        try {
            EditText filterText = (EditText) findViewById(R.id.zipcode);
            Editable zip = filterText.getText();

            LocationLookupService locationLookupService = new LocationLookupService();
            selectedLocation = locationLookupService.getLocationByZip(zip.toString());

            locationHandler.post(launchFindWithLocationInfo);
        } catch (Exception e) {
        }
    }
};

private Runnable launchFindWithLocationInfo = new Runnable() {
    @Override
    public void run() {
        try {
            Intent abc = new Intent(LocationLookup.this, FindWithLocation.class);
            startActivity(abc);
        } catch (Exception e) {

        }
    }
};

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.location);

    locationHandler = new Handler();
    findViewById(R.id.findbyzip).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            getLocationByZip.start();
        }
    });
}

更新

在我给AsyncTask提出了很好的建议后,如果有人发现这一点,那么上面的线程/处理程序模型看起来像下面的asynctask

private class LocationLookupTask extends AsyncTask<String, Void, Location> {
    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        this.dialog = ProgressDialog.show(LocationLookup.this, "", "Loading...");
    }

    @Override
    protected Location doInBackground(String... zips) {
        Location selectedLocation = null;
        for (String zip : zips) {
            LocationLookupService locationLookupService = new LocationLookupService();
            selectedLocation = locationLookupService.getLocationByZip(zip);
        }
        return selectedLocation;
    }

    @Override
    protected void onPostExecute(Location location) {
        this.dialog.dismiss();

        ((AppDelegate) getApplicationContext()).setSelectedLocation(location);
        Intent abc = new Intent(LocationLookup.this, FindWithLocation.class);
        startActivity(abc);
    }
}

现在在onclick中调用它,你会这样做

findViewById(R.id.findbyzip).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                EditText filterText = (EditText) findViewById(R.id.zipcode);
                Editable zip = filterText.getText();

                LocationLookupTask task = new LocationLookupTask();
                task.execute(new String[]{zip.toString()});
            }
        });

3 个答案:

答案 0 :(得分:6)

你不能两次开始一个线程:

  

多次启动线程永远不合法。

取自Thread.start()

因此,您需要创建一个新线程并启动它。

答案 1 :(得分:1)

你不能调用Thread类的start方法的两倍,我建议你也控制onCreate方法中的逻辑,因为根据Activity生命周期可以被Android生命周期Activity Manager调用。

此外,我建议您避免使用此方法,并考虑使用Android SDK提供的AsyncTask。

http://developer.android.com/reference/android/os/AsyncTask.html

答案 2 :(得分:1)

如果你真的想在不创建新课程或使用AsyncTask的情况下这样做,你可以制定一种方法,在每次通话时获得新的Thread

private Thread getLocationByZip;

private void getLocation() {
    getLocationByZip = new Thread() {
        public void run() {
            try {
                EditText filterText = (EditText) findViewById(R.id.zipcode);
                Editable zip = filterText.getText();

                LocationLookupService locationLookupService = new LocationLookupService();
                selectedLocation = locationLookupService.getLocationByZip(zip.toString());

                locationHandler.post(launchFindWithLocationInfo);
            } catch (Exception e) {
            }
        }
    };
    getLocationByZip.start();
}

然后使用getLocationByZip.start()替换代码中的getLocation()。但是,我同意AsyncTask是一个更好的方法,尽管这对你有用。