1.前三天讲了json,handler,今天就用他们来做个简单的天气预报。
2.首先找免费的api接口,,我用的是中国天气网,它的api接口是http://wthrcdn.etouch.cn/weather_mini?city=。
3.接着我们实现界面布局,很简单,首先把布局改为LinearLayout,设置几个textview,button,以及eddittext,为了防止显示不开,可以加上ScrollView,我这里就不加了,代码如下,我这里把语言写死了,如果想让它国际化换一种方式就行了,very simple。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/zijie"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.lenovo.weather.MainActivity">
<TextView
android:paddingTop="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请输入需要查询的城市:" />
<EditText
android:id="@+id/nei"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/chaxun"
android:onClick="Click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/shuchu"/>
<TextView
android:id="@+id/shuchu1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/shuchu2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/shuchu3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/shuchu4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/shuchu5"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/shuchu6"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
4.然后做MainActivity,给button添加事件,再添加个线程得到服务器返回的json,利用handler这个秘书在布局上显示。为什么要用handler,是因为任何线程不能影响主线程,具体代码如下。(这里为了方便初学者,用的是System.out.println,通常用的是log,注意打印要用println,不要用print,会出问题的,这里不多做解释)。
package com.example.lenovo.weather;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Xml;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
public class MainActivity extends AppCompatActivity {
private static final int SUCCESS = 1;
private static final int INVALID = -1;
private EditText editText;
private Button button;
private TextView textView,textView1,textView2,textView3,textView4,textView5, textView6;
private String city;
private String path="http://wthrcdn.etouch.cn/weather_mini?city=";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.chaxun);
editText= (EditText) findViewById(R.id.nei);
textView= (TextView) findViewById(R.id.shuchu);
textView1= (TextView) findViewById(R.id.shuchu1);
textView2= (TextView) findViewById(R.id.shuchu2);
textView3= (TextView) findViewById(R.id.shuchu3);
textView4= (TextView) findViewById(R.id.shuchu4);
textView5= (TextView) findViewById(R.id.shuchu5);
textView6= (TextView) findViewById(R.id.shuchu6);
System.out.println("21");
}
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case SUCCESS:
JSONArray jsonArray= (JSONArray) msg.obj;
System.out.println("你是人吗");
textView.setText("城市:" + city);
try {
textView1.setText(new json().string(jsonArray.getJSONObject(0)));
textView2.setText(new json().string(jsonArray.getJSONObject(1)));
textView3.setText(new json().string(jsonArray.getJSONObject(2)));
textView4.setText(new json().string(jsonArray.getJSONObject(3)));
textView5.setText(new json().string(jsonArray.getJSONObject(4)));
// textView6.setText(new json().string(jsonArray.getJSONObject(5)));
} catch (Exception e) {
e.printStackTrace();
}
break;
case INVALID:break;
}
super.handleMessage(msg);
}
};
public void Click(View v) {
city=editText.getText().toString().trim();//"蚌埠";
System.out.println("123");
System.out.println(city);
if (TextUtils.isEmpty(city))
{
Toast.makeText(MainActivity.this,"bbb",Toast.LENGTH_LONG).show();
}
new Thread(){
@Override
public void run() {
System.out.println("123");
System.out.println(city);
// try {
// System.out.println("123");
// city= URLEncoder.encode(city,"UTF-8");//把汉语转换成URL
// System.out.println(city);
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// System.out.println("234");
System.out.println("234");
String chaxun=path+city;
try {
System.out.println("234");
URL url=new URL(chaxun);
System.out.println("345");
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setConnectTimeout(6000);
System.out.println("456");
if (httpURLConnection.getResponseCode()==200)
{
System.out.println("567");
InputStream inputStream=httpURLConnection.getInputStream();
Input input=new Input();
String s=input.Stream(inputStream);
System.out.println(s);
JSONObject jsonObject=new JSONObject(s);
String result=jsonObject.getString("desc");
System.out.println(result);
if ("OK".equals(result))
{
System.out.println(result);
JSONObject jsonObject1=jsonObject.getJSONObject("data");
String city1=jsonObject1.getString("city");
System.out.println(city1);
JSONArray jsonArray=jsonObject1.getJSONArray("forecast");
System.out.println("2132"+jsonArray.length());
Message message=Message.obtain();
message.what=SUCCESS;//创建标识码
message.obj=jsonArray;//如果数据多可以用bundle携带数据,再把bundle当作参数传递.
//也可以创建一个类。把类当作obj,把数据都送到该类的成员变量中。
//这里你可以只传递天气数据,按上面就行了。这里我想用bundle。
Bundle bundle=new Bundle();
handler.sendMessage(message);
}
else
{
//无效
Message message=Message.obtain();
message.what=INVALID;//无效的
handler.sendMessage(message);
}
}
else
{
Toast.makeText(MainActivity.this,"aaa",Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}.start();
}
}
5.把上次的字符串转换类再复制过来。
package com.example.lenovo.weather;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Created by lenovo on 2020/1/25.
*/
public class Input {
public String Stream(InputStream inputStream)
{
InputStreamReader inputStreamReader=new InputStreamReader(inputStream);
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
StringBuffer buffer=new StringBuffer();
String str="";
try {
while ((str=bufferedReader.readLine())!=null)
{
buffer.append(str);
}
str= buffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
6.为了更好的体现java的包装性,我把json解析专门做了一个类。
package com.example.lenovo.weather;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by lenovo on 2020/1/31.
*/
public class json {
private String date;
private String high;
private String fl;
private String low;
private String fengxiang;
private String type;
public String string(JSONObject jsonObject) throws JSONException {
setDate(jsonObject.getString("date"));
setHigh(jsonObject.getString("high"));
setFl(jsonObject.getString("fengli"));
setLow(jsonObject.getString("low"));
setFengxiang(jsonObject.getString("fengxiang"));
setType(jsonObject.getString("type"));
return getDate()+"\n"+getHigh()+"\n"+getFl()+"\n"+getLow()+"\n"+getFengxiang()+"\n"+getType();
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getFengxiang() {
return fengxiang;
}
public void setFengxiang(String fengxiang) {
this.fengxiang = fengxiang;
}
public String getLow() {
return low;
}
public void setLow(String low) {
this.low = low;
}
public String getFl() {
return fl;
}
public void setFl(String fl) {
this.fl = fl;
}
public String getHigh() {
return high;
}
public void setHigh(String high) {
this.high = high;
}
}
7.加个联网权限。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lenovo.weather">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
8.运行结果如下
9.下次将与自己的服务器建立连接,进行文件多线程下载。