我在从android的网页下载html源码时遇到问题。我在一个不同的线程中运行http客户端,它能够获取html文本(我记录了结果)但后来当我尝试使用下载的html文本时,变量似乎是空主线程。我认为问题正在上升,因为我无法同步线程,但我现在还不知道如何修复它。当我调试代码时,全局变量包含run函数中的数据,但是当我连接线程并查看join方法时,变量为空。这是我的代码(我在不同的线程中运行的类)
公共课LutrijaHr {
public String url;
public String savedHtml;
public LutrijaHr(String s){
this.url = s;
savedHtml = "";
}
public String donwloadSource(String passedUrl) throws Exception{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(passedUrl);
HttpResponse response = client.execute(request);
String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
str.append(line);
}
in.close();
html = str.toString();
savedHtml += html;
return html;
}
}
主类的部分代码:
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
@Override
public void run() {
try {
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
Log.d("test", test);
}
这是我尝试加入线程但变量为空的部分
if (v.getId() == R.id.checkNumber){
Thread t = new Thread(new LotoMain(), "Page thread");
t.start();
try {
t.join();
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
我想在不使用android asynctask类的情况下解决这个问题,因为我想了解一下线程及其运行方式。
答案 0 :(得分:0)
使用"锁定" 将此代码添加到主类:
public Lock workingLock = new ReentrantLock();
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
@Override
public void run() {
try {
workingLock.lock();
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
workingLock.unlock;
Log.d("test", test);
}
现在用于:
if(v.getId()== R.id.checkNumber){ 线程t =新线程(新的LotoMain(),"页面线程");
try {
try {
workingLock.lock();
} catch (Exception e) {
e.printStackTrace();
}
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
workingLock.unlock();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
答案 1 :(得分:0)
试试这个,它会将给定页面的源代码作为一个长字符串返回,然后您可以根据需要进行操作,并且作为一个独立的类/方法,您可以在UI线程或asyc上调用它,或者您选择到。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class WebPage {
public static String getWebSource(String Url) throws IOException {
URL url = new URL(Url);
URLConnection urlConnection = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "UTF-8"));
String inputLine;
StringBuilder sb = new StringBuilder();
while ((inputLine = br.readLine()) != null)
sb.append(inputLine);
br.close();
return sb.toString();
}
}
编辑:如果你想从UI线程调用它,android默认让你这么做。你需要更改应用程序线程策略,这可以通过在应用程序启动时运行它来完成(需要最小API为9)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
答案 2 :(得分:0)
我"解决了#34;声明的问题
字符串测试="&#34 ;; 如
static String test ="&#34 ;;
即使这种灵魂有效,我也不明白为什么它不能用我原来的解决方案。如果有人可以为我点亮这将是非常有帮助的