Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我能';在我的活动中不启动2个线程?_Java_Android_Multithreading - Fatal编程技术网

Java 为什么我能';在我的活动中不启动2个线程?

Java 为什么我能';在我的活动中不启动2个线程?,java,android,multithreading,Java,Android,Multithreading,我将活动中的web服务调用推送到线程(如下所示)。我第一次在活动中执行此操作时,它工作正常(从我的edittext获取文本并加载服务以获取lat/lng数据) 但是,当我单击后退按钮(emulator)并再次尝试触发此线程时,它在.start()之后爆炸;在我的点击处理程序中。我可能做错了什么?谢谢 private Thread getLocationByZip = new Thread() { public void run() { try {

我将活动中的web服务调用推送到线程(如下所示)。我第一次在活动中执行此操作时,它工作正常(从我的edittext获取文本并加载服务以获取lat/lng数据)

但是,当我单击后退按钮(emulator)并再次尝试触发此线程时,它在.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);
    }
}

一个线程不能启动两次:

多次启动线程是不合法的

摘自


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

一个线程不能启动两次:

多次启动线程是不合法的

摘自


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

您不能两次调用thread类的start方法,我建议您也控制方法onCreate中的逻辑,因为根据活动的生命周期,Android lifecycle Activity Manager可能会调用该方法

此外,我建议您避免使用这种方法,并考虑使用Android SDK提供的异步任务。


您不能两次调用Thread类的start方法,我建议您也控制方法onCreate中的逻辑,因为根据活动的生命周期,Android lifecycle Activity Manager可能会调用该方法

此外,我建议您避免使用这种方法,并考虑使用Android SDK提供的异步任务。


如果您确实想在不创建新类或不使用
AsyncTask
的情况下执行此操作,您可以创建一个方法,在每次调用时获取一个新的
线程

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
是一种更好的方法,尽管这对您来说很有用。

如果您真的想在不创建新类或不使用
AsyncTask
的情况下执行此操作,您可以在每次调用时创建一个新的
线程

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
将是一种更好的方法,尽管这对您来说是可行的。

@Toran-最简单的方法是创建
公共类LocationZipThread extensed Thread{…}
。然后,您可以根据需要制作任意多的线程。但是,您应该在这里使用AsyncTask。@Toran-最简单的方法是创建
公共类LocationZipThread extends Thread{…}
。然后,您可以根据需要制作任意多的线程。但是,您应该在这里使用AsyncTask,应该是这样的,因为没有任何内容被修改,他只在getText()中使用它。为了超级安全起见,他可以向方法传递一个包含已检索文本的字符串,但我认为这在这里无关紧要。应该是这样的,因为没有任何内容被修改,他只在getText()中使用它。为了超级安全起见,他可以向方法传递一个包含已检索文本的字符串,但我认为这并不重要。