我主要使用C#并开始用Java开发。我无法启动线程:(
public class GetLocationInfo implements Runnable{
String address;
double latitude;
double longitude;
public void run() {
HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng=42.993504,-79.239167&sensor=false");
//HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8"));
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("formatted_address")) {
address = reader.nextString();
} else
reader.skipValue();
}
reader.endObject();
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
public String GetAddress(double lat, double lng) {
latitude = lat;
longitude = lng;
Thread thread = new Thread(this);
thread.start();
return address;
}
}
我在重写的run()方法中设置了断点,似乎没有任何东西在此方法中执行。如果你们能帮助我理顺这一点,那将非常感激。
干杯
答案 0 :(得分:1)
不建议使用这种方式获取位置,我会使用谷歌服务在这里发挥一个很好的例子。
http://www.tutorialspoint.com/android/android_location_based_services.htm
如果您决定使用该代码,我建议您使用AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
答案 1 :(得分:1)
通过假设主线程以某种方式停止并等待新创建的线程在返回之前执行其run()
方法,您缺少关于线程的一些重要观点。
使用线程时,请记住以下几点:
GetAddress()
方法启动帖子时,它并不意味着它会立即调用它的run方法,只是在它返回时继续返回计算的地址,就好像你有在不创建新线程的情况下调用run方法。如果你想要的话,你甚至不需要另一个线程。当你启动第二个线程时,你基本上告诉操作系统有一个新的线程准备好运行,但由操作系统决定该线程中的代码何时实际开始。即使在多CPU /核心环境中,您也无法假设核心将在该确切位置可用。你也不能假设主线程会因为它启动了另一个线程而停止或暂停它的执行。主线程最终可能会暂时停止执行以允许其他线程执行,但仅当系统中没有足够的内核并行运行所有线程时才会执行。无论如何,你无法预测何时或是否会发生。这意味着在启动新线程之后,方法GetAddress()
将更有可能继续在新创建的线程完成或甚至启动其{{1}之前将地址变量的当前值返回给其调用者。方法。
如果您不确定是否为真,请在启动线程后插入以下行:
run()
此代码强制主线程等待新创建的线程执行。 但请注意,此代码会破坏创建新主题的任何好处。
那么现在呢?
你有很多方法可以处理多个线程,我不能告诉你什么是最好的方法,而不了解你的项目更多;但我可以通过一个非常简单的例子给你一些指示
让我们假设你有一个带有UI的程序,一个获取地址的按钮和一个写入地址的文本字段。当有人单击该按钮时,您不会尝试一次性计算地址,而是调用thread.start();
try { // Used just for demonstration purposes
thread.join(); // This block kills the parallelism of the second thread
}
return address;
之类的方法,在该方法中启动工作线程并使用startRetrievingAddress()
之类的临时文本填充文本字段。在工作线程的"please wait..."
方法结束时,您可以添加代码以使用最终结果填充文本字段。
更好的方法是创建一个支持" completition"的工作线程类。当run方法完成计算地址时会收到通知的监听器,这样他们就有机会在计算结果后立即处理结果。然后,您将注册一个监听器,您将使用计算值设置文本字段。
当然有更好的方法可以使用looper线程来处理从工作线程发出的消息,但我不能在这里提及它们。祝你好运!
答案 2 :(得分:0)
我建议你封装核心活动'在实现runnable或callable的类中(如果您希望获得Future结果)。使用ThreadpoolExecutors提交任务。
答案 3 :(得分:0)
谢谢你们给出一些答案。虽然它的编码方式可能不是最佳实践,但我找到了解决方案。
刚刚为类创建了一个构造函数并在那里启动了线程并使字符串变量地址为public。
public class GetLocationInfo implements Runnable{
public String address;
double latitude;
double longitude;
public GetLocationInfo(double lat, double lng) {
latitude = lat;
longitude = lng;
Thread thread = new Thread(this);
thread.start();
}
public void run() {
HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng=42.993504,-79.239167&sensor=false");
//HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
JsonReader reader = new JsonReader(new InputStreamReader(stream, "UTF-8"));
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("formatted_address")) {
address = reader.nextString();
} else
reader.skipValue();
}
reader.endObject();
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
}