[英](Java) Thread won't execute
我主要使用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()方法中設置了斷點,並且在此方法中似乎沒有任何執行。 如果你們能幫助我弄清楚這一點,將不勝感激。
干杯
不建議使用這種方式取得位置,我會在這里使用Google服務起到很好的作用。
http://www.tutorialspoint.com/android/android_location_based_services.htm
如果您確定要使用該代碼,建議您使用AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html
通過假設主線程以某種方式停止並等待新創建的線程在返回之前執行其run()
方法,您會丟失一些關於線程的重要信息。
使用線程時,請記住以下幾點:
GetAddress()
方法中啟動線程時,這並不意味着它將立即調用它的run方法,而只是在返回時返回計算的地址,就好像您已調用run方法而不創建新線程一樣。 如果您只想要一個線程,那么您甚至不需要另一個線程。 當您啟動第二個線程時,您基本上是在告訴OS已有一個新線程可以運行,但是由OS來決定該線程中的代碼實際何時啟動。 即使在多CPU /內核環境中,您也不能假定在那個確切時間點內核就可用。 您也不能僅僅因為主線程啟動了另一個線程就假定主線程會停止或暫停其執行。 主線程最終可能會短暫停止執行以允許其他線程執行,但前提是系統中的內核不足以並行運行所有線程。 無論如何,您無法預測何時或是否會發生。 這意味着在啟動新線程之后,在新創建的線程完成甚至啟動其run()
方法之前, GetAddress()
方法更有可能繼續將地址變量的當前值返回給其調用方。
如果不確定是否為真,請在啟動線程后嘗試插入以下行:
thread.start(); try { // Used just for demonstration purposes thread.join(); // This block kills the parallelism of the second thread } return address;
此代碼強制主線程等待新創建的線程執行。 但是請注意,此代碼將破壞創建新線程的任何好處。
所以現在怎么辦?
您有多種處理多個線程的方法,而我不了解您的項目就無法告訴您什么是最好的方法。 但我可以通過一個非常簡單的示例為您提供一些指導。
假設您有一個帶有UI的程序,一個用於獲取地址的按鈕以及一個將寫入地址的文本字段。 當某人單擊該按鈕時,您無需嘗試startRetrievingAddress()
計算地址,而是調用諸如startRetrievingAddress()
的方法,在該方法中,您將啟動工作線程並在文本字段中填充臨時文本,例如"please wait..."
。 在工作線程的run()
方法末尾,您可以添加代碼以用最終結果填充文本字段。
更好的方法是創建一個支持“完成”偵聽器的工作線程類,當run方法完成地址計算后會通知該線程,以便他們有機會立即處理結果計算。 然后,您將注冊一個偵聽器,在其中將使用計算出的值設置文本字段。 當然,還有更好的方法可以使用彎針線程來處理從工作線程發出的消息以及所有消息,但我不能在這里全部提及。 祝好運!
我建議您將“核心活動”封裝在實現可運行或可調用的類中(如果您希望獲得Future結果)。 使用ThreadpoolExecutors提交任務。
謝謝你們給我一些答案。 盡管它的編碼方式可能不是最佳實踐,但我找到了解決方案。
剛剛為該類創建了一個構造函數,並在那里啟動了線程,並將字符串變量地址設為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) {
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.