65.9K
CodeProject 正在变化。 阅读更多。
Home

如何使用HTTP URL Connection方法调用服务

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.43/5 (7投票s)

2017 年 2 月 7 日

Ms-RL

2分钟阅读

viewsIcon

23822

在本教程中,我们将使用 GET 方法调用一个服务,并将示例 JSON 数据填充到 RecyclerView 中,而无需使用任何外部库。

示例 JSON

这是一个非常简单的 JSON,它提供了《权力的游戏》的列表详情,其中每个节点包含一些信息,例如战争名称、地点、地区、进攻方国王和防守方国王。

JSON Sample:-
[
{
    "name": "Battle of the Golden Tooth",
    "attacker_king": "Joffrey/Tommen Baratheon",
    "defender_king": "Robb Stark",
    "location": "Golden Tooth",
    "region": "The Westerlands"
  },
  {
    "name": "Battle at the Mummer's Ford",
    "attacker_king": "Joffrey/Tommen Baratheon",
    "defender_king": "Robb Stark",
    "location": "Mummer's Ford",
    "region": "The Riverlands"
  }
]

您可以通过访问以下网址获取此 JSON 数据:

URL: https://blogurl-3f73f.firebaseapp.com/

我假设您对 JSON 格式有基本的了解。

创建新项目

在 Android Studio 中从文件 ⇒ 新项目创建新项目,填写所需详细信息。

由于我们需要进行网络请求,因此需要在 AndroidManifest.xml 中添加 INTERNET 权限。

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

在 RecyclerView 中填充数据

要启用 RecyclerView 和 Card View 元素,您需要在 build.gradle 文件中添加依赖项:

dependencies {    
compile fileTree(dir: 'libs', include: ['*.jar']) 
compile 'com.android.support:appcompat-v7:25.1.0'  
testCompile 'junit:junit:4.12'
compile 'com.android.support:cardview-v7:25.0.1'
compile 'com.android.support:recyclerview-v7:25.0.1'
   }

在进行 http 调用之前,首先在我们的主 Activity 中添加一个按钮和一个 RecyclerView。打开主 Activity 的布局文件 (activity_main.xml),并添加一个 ButtonRecyclerView 元素。

    <Button    
      android:id="@+id/btnCreateConnection"  
      android:layout_width="match_parent"   
      android:layout_height="wrap_content"  
      android:text="Create Connection"/>
 
    <android.support.v7.widget.RecyclerView  
      android:id="@+id/recyclerView"
      android:layout_width="match_parent"    
      android:layout_height="match_parent"/>

由于我们通过进行 HTTP 调用来获取 JSON,因此我添加了一个 AsyncGetWarInfo,以便在后台线程中进行 http 调用。在您的主 Activity 类中添加以下方法。

doInBackground() 方法中,调用 HTTP_URL_CONNECTION_GET() 从 URL 获取 json。一旦获取到 json,就会对其进行解析,并将每个联系人添加到数组列表中。

请注意,我根据节点的类型使用了 getJSONArray()getJSONObject() 方法。

package com.bytemachine.urlconnectionwithrecyclerview;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    // declaring variables
    Button btnCreateConnection;
    RecyclerView recyclerView;
    List<ModelWarDetails> listWarDetails=new ArrayList<>();
    RecyclerViewAdapter adapter;
    LinearLayoutManager llm;

    //onCreate calls when the application loads for the first time.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView= (RecyclerView) findViewById(R.id.recyclerView);

        llm=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(llm);

        btnCreateConnection= (Button) findViewById(R.id.btnCreateConnection);

        //setting click event on Button
        btnCreateConnection.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //executing Async task class to create HTTP connection
                new FetchWarsInfo().execute();
            }
        });
    }

    /**
     * Async task class to get json response by making HTTP call
     * Async task class is used because 
     * you cannot create a network connection on main thread
     */
    public class FetchWarsInfo extends AsyncTask<Void, Void, Void> {

        ProgressDialog progressDialog;
        static final String URL_STRING = 
        "https://blogurl-3f73f.firebaseapp.com/";
        String response;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(MainActivity.this);
            progressDialog.setCancelable(false);
            progressDialog.setMessage("Please wait. Fetching data..");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setProgress(0);
            progressDialog.show();
         }

        @Override
        protected Void doInBackground(Void... voids) {
            /*
            creatingURLConnection is a function use to establish connection
            */
            response = creatingURLConnection(URL_STRING);
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            progressDialog.dismiss();
            Toast.makeText(getApplicationContext(),
            "Connection successful.",Toast.LENGTH_SHORT).show();

            try{
                if(response!=null && !response.equals("")){
                    /*
                    converting JSON response string into JSONArray
                    */

                    JSONArray responseArray = new JSONArray(response);
                    if(responseArray.length()>0){
                        /*
                        Iterating JSON object from JSON Array one by one
                        */
                        for(int i=0;i<responseArray.length();i++){
                            JSONObject battleObj = responseArray.getJSONObject(i);

                            //creating object of model class(ModelWarDetails)
                            ModelWarDetails modelWarDetails = new ModelWarDetails();
                            /*
                            fetching data based on key from JSON and setting into model class
                            */
                            modelWarDetails.setName(battleObj.optString("name"));
                            modelWarDetails.setAttacker_king
                            (battleObj.optString("attacker_king"));
                            modelWarDetails.setDefender_king
                            (battleObj.optString("defender_king"));
                            modelWarDetails.setLocation(battleObj.optString("location"));

                            //adding data into List
                            listWarDetails.add(modelWarDetails);

                        }

                        //calling RecyclerViewAdapter constructor by passing context and list
                        adapter = new RecyclerViewAdapter(getApplicationContext(),listWarDetails);

                        //setting adapter on recyclerView
                        recyclerView.setAdapter(adapter);

                        // to notify adapter about changes in list data(if changes)
                        adapter.notifyDataSetChanged();

                    }
                }else {
                    Toast.makeText(getApplicationContext(),
                                   "Error in fetching data.",Toast.LENGTH_SHORT).show();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public String creatingURLConnection (String GET_URL) {
        String response = "";
        HttpURLConnection conn ;
        StringBuilder jsonResults = new StringBuilder();
        try {
            //setting URL to connect with
            URL url = new URL(GET_URL);
            //creating connection
            conn = (HttpURLConnection) url.openConnection();
            /*
            converting response into String
            */
            InputStreamReader in = new InputStreamReader(conn.getInputStream());
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }
            response = jsonResults.toString();
        }catch(Exception e){
            e.printStackTrace();
        }
        return response;
    }
}

创建另一个名为 list_war_details.xml 的布局文件,内容如下。这将用于渲染单个列表项视图。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="4dp"
        android:layout_margin="8dp"
        app:cardCornerRadius="4dp"
        app:cardBackgroundColor="#FFFFFF"
        android:id="@+id/layoutCard">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:padding="16dp">

                    <ImageView
                        android:layout_width="36dp"
                        android:layout_height="36dp"
                        android:id="@+id/imageView2"
                        android:src="@drawable/image_crown1"/>
                </LinearLayout>

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingLeft="8dp"
                    android:paddingRight="8dp"
                    android:paddingBottom="8dp"
                    android:paddingTop="8dp">

                    <TextView
                        android:text="TextView"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/txtName"
                        android:paddingTop="4dp"
                        android:paddingBottom="4dp"
                        android:textSize="18sp"
                        android:textColor="#000000" />

                    <TextView
                        android:text="TextView"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/txtLocation"
                        android:paddingBottom="4dp"
                        android:textSize="12sp" />

                </LinearLayout>

            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="0.1dp"
                android:background="#d1d1d1"></View>

            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="16dp"
                android:paddingRight="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="8dp">

                <TextView
                    android:text="Attacker King"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/txtAttackerKing"
                    android:layout_weight="1"
                    android:paddingTop="4dp"
                    android:paddingBottom="4dp" />

                <TextView
                    android:text="Defender King"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/txtDefenderKing"
                    android:layout_weight="1"
                    android:gravity="right"
                    android:paddingBottom="4dp"
                    android:paddingTop="4dp" />
            </LinearLayout>
        </LinearLayout>

    </android.support.v7.widget.CardView>
</LinearLayout>

在添加 RecyclerView 部件后,让我们开始编写 adapter 类来渲染数据。

为此,您需要创建一个名为 ModelWarDetails.java 的模型类,并声明 namelocationattacker_kingdefender_king。 此外,为每个变量添加 getter/setter 方法。

创建一个 DAO(数据访问对象),通常称为 Modal 类,名为 ModelWarDetails.java。 声明变量(namelocationattacker_kingdefender_king),并生成 getter 和 setter。

:您可以通过按 alt + insert 生成 getter 和 setter。

package com.bytemachine.urlconnectionwithrecyclerview;

class ModelWarDetails {

    private String name;
    private String location;
    private String attacker_king;
    private String defender_king;
    private String defender_king1;

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

     String getLocation() {
        return location;
    }

    void setLocation(String location) {
        this.location = location;
    }

    String getAttacker_king() {
        return attacker_king;
    }

    void setAttacker_king(String attacker_king) {
        this.attacker_king = attacker_king;
    }

    String getDefender_king() {
        return defender_king;
    }

    void setDefender_king(String defender_king) {
        this.defender_king = defender_king;
    }
}

现在创建一个名为 RecyclerViewAdapter.java 的类,并添加以下代码。 在这里,onCreateViewHolder() 方法会加载 list_war_details.xml。 在 onBindViewHolder() 方法中,将适当的战争数据(namelocationattacker_kingdefender_king)设置为每一行。

getItemCount() 方法给出列表的大小。

package com.bytemachine.urlconnectionwithrecyclerview;

import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;

 class RecyclerViewAdapter extends 
 RecyclerView.Adapter<RecyclerViewAdapter.ViewHolderWarDetails> {

     // declaring variables
     private Context context;
     private List<ModelWarDetails> listWarDetails;

     //constructor
     RecyclerViewAdapter(Context context, List<ModelWarDetails> listWarDetails) {
        this.context = context;
        this.listWarDetails = listWarDetails;
    }

    @Override
    public ViewHolderWarDetails onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.list_war_details,parent,false);
        ViewHolderWarDetails viewHolderWarDetails = new ViewHolderWarDetails(view);

        return viewHolderWarDetails;
    }

    @Override
    public void onBindViewHolder(ViewHolderWarDetails holder, int position) {

        //setting data on each row of list according to position.

        holder.txtName.setText(listWarDetails.get(position).getName());
        holder.txtLocation.setText(listWarDetails.get(position).getLocation());
        holder.txtAttackerKing.setText(listWarDetails.get(position).getAttacker_king());
        holder.txtDefenderKing.setText(listWarDetails.get(position).getDefender_king());
    }

     //returns list size

    @Override
    public int getItemCount() {
        return listWarDetails.size();
    }

     class ViewHolderWarDetails extends RecyclerView.ViewHolder{

         // declaring variables
         TextView txtName, txtLocation, txtAttackerKing,txtDefenderKing;
         CardView layoutCard;

         ViewHolderWarDetails(View v) {
            super(v);

            txtName = (TextView) v.findViewById(R.id.txtName);
            txtLocation = (TextView) v.findViewById(R.id.txtLocation);
            txtAttackerKing = (TextView) v.findViewById(R.id.txtAttackerKing);
            txtDefenderKing = (TextView) v.findViewById(R.id.txtDefenderKing);
            layoutCard = (CardView) v.findViewById(R.id.layoutCard);
        }
    }
}

现在,如果您运行该应用程序,您将看到战争详情以列表方式显示。

请随时通过 bytemachines.inc@gmail.com 与我联系。

祝您编码愉快!

© . All rights reserved.