1. 程式人生 > >Android 天氣預報(使用okHttp、AsyncTask訪問和風天氣並Gosn解析資料)

Android 天氣預報(使用okHttp、AsyncTask訪問和風天氣並Gosn解析資料)

第一步老規矩導架包,都是開源哦

在專案的配置檔案中新增
在這裡插入圖片描述
在這裡插入圖片描述

compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.9.0'
compile 'com.google.code.gson:gson:2.8.0'

第二步新增許可權

在清單檔案AndroidManifest.xml中新增

<uses-permission android:name="android.permission.INTERNET"/>

第三步佈局(activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/et_cityname" android:hint="請輸入城市名字" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content"
/> <Button android:id="@+id/btn_select_weather" android:text="查詢" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <TextView android:id="@+id/tv_werther_conten" android:textSize="20sp" android:text="測試" android:layout_gravity="center" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>

第四步活動內訪問(MainActivity.class)

package com.example.myapplication2;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    private final String KEY = "e1984444a03d4a52a1f6cc545cce9245";
    private TextView tv_werther_conten;
    private EditText et_cityname;
    private Button btn_select_weather;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Werther werther= (Werther) msg.obj;
            switch(msg.what){
                case 1:
                    tv_werther_conten.setText("時間:" + String.valueOf(werther.getHeWeather6().get(0).getUpdate().getLoc()) +
                            "、地點:" + werther.getHeWeather6().get(0).getBasic().getLocation() +
                            "、天氣:" + werther.getHeWeather6().get(0).getNow().getCond_txt() +
                            "、風向:" + werther.getHeWeather6().get(0).getNow().getWind_dir() +
                            "、氣溫:" + werther.getHeWeather6().get(0).getNow().getTmp());
                    break;
            }
            Log.d(TAG, "onResponse: " + String.valueOf(werther.getHeWeather6().get(0).getUpdate().getLoc()));

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initDate();
        btn_select_weather.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String cityname = String.valueOf(et_cityname.getText());
                if (cityname.equals("")) {
                    Toast.makeText(MainActivity.this, "城市名不能為空", Toast.LENGTH_SHORT).show();
                } else {
                    String url = "https://free-api.heweather.com/s6/weather/now?key=e1984444a03d4a52a1f6cc545cce9245&location=" + cityname;
                    new MyAsyncTask().execute(url);

                }
            }
        });
    }

    private void initDate() {

    }

    private void initView() {
        tv_werther_conten = (TextView) this.findViewById(R.id.tv_werther_conten);
        et_cityname = (EditText) this.findViewById(R.id.et_cityname);
        btn_select_weather = (Button) this.findViewById(R.id.btn_select_weather);
    }

    private void getWerther(String url) {
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()//預設就是GET請求,可以不寫
                .build();
        Log.d(TAG, "url: " + url);
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

                Log.d(TAG, "onFailure: ");
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseData = response.body().string();
                Log.d(TAG, "onResponse: " + responseData);
                Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();
                Werther werther = gson.fromJson(responseData, Werther.class);
                Message message=new Message();
                message.what=1;
                message.obj=werther;
                handler.sendMessage(message);
            }
        });

    }

    class MyAsyncTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... strings) {
            String url = strings[0];
            getWerther(url);
            return null;
        }
    }
}

講一下這其中的注意點:

1.String responseData = response.body().string();訪問成功之後拿到的資料
在這裡插入圖片描述
你可以複製上面的地址給個城市中文拼音都可以
拿到這個資料之後
Json自動建立module網站
進這個網站
在專案中建立這些類
在這裡插入圖片描述
用上自己的包名和第一個類名
在這裡插入圖片描述
在解析過程中如果內容不多可以不用這種方式。畢竟還是有點小麻煩的。
可以直接原生態

String json = "{\n" +
                "  \"rst\": 0,\n" +
                "  \"msg\": \"ok\",\n" +
                "  \"data\": {\n" +
                "    \"cookie\": \"JSESSIONID=abcntKeuJhop56LGykfdw\"\n" +
                "  }\n" +
                "}";
        JsonObject jsonObject = (JsonObject) new JsonParser().parse(json);
        System.out.println("rst:" + jsonObject.get("rst").getAsInt());
        System.out.println("msg:" + jsonObject.get("msg").getAsString());
        System.out.println("data:" + jsonObject.get("data").getAsJsonObject().get("cookie").getAsString());

2.附上和服天氣的介面地址,你可以從中拿你所需要的資料並放到介面中顯示,key我也給你了,不同的介面地址不一樣,自己注意哦。
和風天氣介面地址
3.更改UI要在主執行緒中進行,不然會報錯。所以我用到了Handler
大概意思和你說一下:

你在訪問網路過程中是開了一個子執行緒,而你的主執行緒會繼續執行下去,當你訪問並獲取資料的時候再更新UI,你的主執行緒已經跑完了。

總結:

1.在開發的過程中不能急,雖然說拿別人的程式碼會改就行,但是還是要自己理解和看懂。
2.沒事像小白一樣多寫寫,就記住了。不能每天都學習新知識。好像是拿了玉米丟了桃子,消化了在拿不是美滋滋。