我正在开发一个应用程序,它使用 PHP 和 JSON 从 MySQL 数据库中提取天气数据。它检查用户是否有互联网连接,如果没有,它将查找本地存储的文件。如果该文件不存在,那么它将显示一条消息。要刷新列表,用户必须重新启动应用程序。我发现这对用户不太友好,所以我决定添加一个刷新数据的按钮。
我有两个类,我的 ListActivity 类(在下面的代码中称为 WeerActivity.java)和一个在新线程中从 Internet 收集所有数据的类(称为 InternetWeerThread.java)。我的 onClickListener,对于刷新按钮,是在 ListActivity 类中设置的。这会尝试将包含刷新代码的可运行文件发布到另一个类。但是,当我这样做时。我得到一个异常,因为代码仍然在 UI 线程上执行。
WeerActivity.java
public class WeerActivity extends ListActivity{
private static Thread internetWeerThread;
private InternetWeerThread internetWeerThreadInstance;
public static Handler activityHandler;
public static Handler internetHandler;
public static ListView listView;
public static Context context;
public static LinearLayout weerContainer;
public static Button refreshButton;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.weer);
refreshButton = (Button) findViewById(R.id.weer_refresh_button);
listView = (ListView)findViewById(android.R.id.list);
weerContainer = (LinearLayout) findViewById(R.id.weer_container);
context = this;
activityHandler = new Handler();
internetWeerThreadInstance = new InternetWeerThread(activityHandler);
internetWeerThread = internetWeerThreadInstance;
internetHandler = InternetWeerThread.getHandler();
internetWeerThread.start();
refreshButton.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v){
internetHandler.post(internetWeerThreadInstance.new Refresh());
}
});
}
}
InternetWeerThread.java
class InternetWeerThread extends Thread{
private Handler activityHandler;
private static String html;
private static JSONArray weerItems;
private static ArrayList<WeerData> weerData = new ArrayList<WeerData>();
private static WeerAdapter adapter;
private static String JSONString;
private static final String timeoutString = "Unable to connect with the server, check your internet connection";
private static final Handler internetWeerThread = new Handler();
// CONSTRUCTOR
public InternetWeerThread(Handler activityHandler){
this.activityHandler = activityHandler;
}
public static Handler getHandler(){
return internetWeerThread;
}
@Override
public void run(){
onRefresh();
}
// method that gets called by the Runnable Refresh (and onCreate)
private void onRefresh(){
try{
weerItems = getWeerItems("http://192.168.178.14/weer.php");
JSONString = weerItems.toString();
FileAccess.createFile(WeerActivity.context, "weer.txt", JSONString);
displayData(weerItems);
}catch(IOException e){
e.printStackTrace();
System.out.println(WeerActivity.context);
if(FileAccess.fileExists(WeerActivity.context, "weer.txt")){ // read data from file
JSONArray JSONData;
try {
if(FileAccess.readFile(WeerActivity.context, "weer.txt") != null){
JSONData = new JSONArray(FileAccess.readFile(WeerActivity.context, "weer.txt"));
displayData(JSONData);
activityHandler.post(new Updater());
}else{
activityHandler.post(new TimeOut());
}
} catch (JSONException je) {
je.printStackTrace();
activityHandler.post(new TimeOut());
}
}else{ // display message that there is no internet connection and no file present
activityHandler.post(new TimeOut());
}
}
}
private JSONArray getWeerItems(String link) throws IOException{
HttpUriRequest request = new HttpGet(link.toString());
BasicHttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
ConnManagerParams.setTimeout(httpParameters, timeoutConnection);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(request);
if(response.getStatusLine().getStatusCode() == 200){
JSONArray jArray = new JSONArray();
try {
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream(con.getInputStream());
try {
jArray = new JSONArray(html);
} catch (JSONException e) {
e.printStackTrace();
}
return jArray;
}catch (Exception e) {
e.printStackTrace();
}
return jArray;
}else{
activityHandler.post(new TimeOut());
JSONArray jArray = new JSONArray();
return jArray;
}
}
private void readStream(InputStream in){
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
html = "";
while ((line = reader.readLine()) != null) {
html += line;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void displayData(JSONArray jArray){
try{
int length;
if(jArray.length() < 7){
length = jArray.length();
}else if (jArray.length() > 7){
length = 7;
}else{
length = 7;
}
for(int i = 0; i < length; i++){
JSONObject row = jArray.getJSONObject(i);
int temperatureDay = row.getInt("temperature_day");
int temperatureNight = row.getInt("temperature_night");
String date = row.getString("date");
int weatherType = row.getInt("weather_type");
WeerData singleWeerData = new WeerData();
singleWeerData.setTemperatureDay(temperatureDay);
singleWeerData.setTemperatureNight(temperatureNight);
singleWeerData.setDate(date);
singleWeerData.setWeatherType(weatherType);
weerData.add(i, singleWeerData);
}
activityHandler.post(new Updater());
}catch(JSONException e){
e.printStackTrace();
}
}
// update the listView
public class Updater implements Runnable{
public void run(){
adapter = new WeerAdapter(WeerActivity.context, R.layout.weer_row, weerData);
WeerActivity.listView.setAdapter(adapter);
}
}
线程和 Runnables 对我来说是新的。这是我正在创建的第一个 Android 应用程序。所以希望有人可以帮助我解决这个问题。
任何帮助将不胜感激 !