天天看點

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

1. 介紹及第三方資料庫的搭建

【說明】伺服器的開發:主要是接口的開發和管理(怎麼和資料庫互動)

1.1  服務端的接口清單

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

1.2 資料庫的表

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

1.3 第三方資料庫的使用

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立應用和綁定服務】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【釋出管理】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立第一張表】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立第二張表】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2. 服務端接口api、部署測試、測試

【開發環境】使用的是javaEE工具包;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【說明】首先建立的是CreateRoom,建立房間号,其他的伺服器接口與此大同小異;

2.1 資料庫資料的建表、查詢

【建立項目】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【增加severlet包】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立類】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【參數說明】

【HttpServletRequest req】請求的參數包含在此參數中

【HttpServletResponse resp】傳回的資料的在此參數中

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

 【請求參數的擷取】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【資料庫插入資料】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【查詢語句并發送結果】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.2 配置xml

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.3 釋出

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

釋出成功之後就可以通路了;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.4【bug】

【bug】增加調試資訊可以使用system.out.print();在網頁的控制台存在背景運作的資訊;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【說明】因為現在的字段的值為空,是以需要增加雙引号;兩個逗号之間都存在“反斜杠”

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.5 容錯的添加

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.6 伺服器錯誤資訊的傳回

【說明】

【情況1】如果是錯誤的狀态和資訊,則errCode和errMsg中存在相應的内容;data字段為null;

【情況2】如果是正常的狀體,則errCode和errMsg中為null;data字段傳回相應的内容;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【源碼】/ImoocBearLive/src/imooc/bear/live/ResponseObject.java

1 package imooc.bear.live;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.http.HttpServletResponse;
 7 
 8 import com.google.gson.Gson;
 9 
10 public class ResponseObject {
11 
12     public static final String CODE_SUCCESS = "1";
13     public static final String CODE_FAIL = "0";
14 
15     private static Gson GsonInstance = new Gson();
16 
17     public String code;
18     public String errCode;
19     public String errMsg;
20     public Object data;
21 
22 
23     public static ResponseObject getSuccessResponse(Object data) {
24         ResponseObject responseObject = new ResponseObject();
25         responseObject.code = CODE_SUCCESS;
26         responseObject.errCode = "";
27         responseObject.errMsg = "";
28         responseObject.data = data;
29         return responseObject;
30     }
31 
32     public static ResponseObject getFailResponse(String errCode, String errMsg) {
33         ResponseObject responseObject = new ResponseObject();
34         responseObject.code = CODE_FAIL;
35         responseObject.errCode = errCode;
36         responseObject.errMsg = errMsg;
37         responseObject.data = null;
38         return responseObject;
39     }
40 
41 }      

 【錯誤資訊的封裝】/ImoocBearLive/src/imooc/bear/live/Error.java

1 package imooc.bear.live;
 2 
 3 public class Error {
 4     
 5     public static final String errorCode_Exception = "500";
 6     private static final String errorMsg_Exception = "伺服器異常";
 7 
 8     public static String getExceptionMsg(String e) {
 9         return errorMsg_Exception + ":" + e;
10     }
11 }      

【錯誤資訊的擷取】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【userId的檢查報錯】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【測試】再次打包,釋出,然後運作測試;傳回的錯誤的資訊為亂碼,需要對編碼做相容的修改;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【編碼的相容】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【測試】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【資料的傳回】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

2.7 完善roomId的資訊

【說明】之前傳回的隻是一個id的int值,應該完善為一個對象;

 【修改之前傳回的數值】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【修改】将所有的資料全部傳回;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立該類】封裝好要封裝的對象;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

[源碼]/ImoocBearLive/src/imooc/bear/live/RoomInfo.java

1 package imooc.bear.live;
 2 
 3 public class RoomInfo {
 4     public int roomId;
 5     public String userId;
 6     public String userName;
 7     public String userAvatar;
 8     public String liveCover;
 9     public String liveTitle;
10     public int watcherNums;
11 }      

 【修改邏輯中傳回的對象】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

3. 建立直播接口的調用--缺少内容

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【網絡使用的庫】網絡直接使用okhttp庫;七牛庫中已經存在了;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

4.服務端接口優化

【說明】優化分為兩處;

4.1 servlet的分發優化

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【拷貝的内容是一大段的内容】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

 【調用action處理對象】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【源碼】/ImoocBearLive/src/imooc/bear/live/RoomServlet.java

1 package imooc.bear.live;
 2 
 3 import imooc.bear.live.action.CreateRoomAction;
 4 import imooc.bear.live.action.GetRoomListAction;
 5 import imooc.bear.live.action.GetWatchersAction;
 6 import imooc.bear.live.action.HeartBeatAction;
 7 import imooc.bear.live.action.JoinRoomAction;
 8 import imooc.bear.live.action.QuitRoomAction;
 9 
10 import java.io.IOException;
11 import java.sql.SQLException;
12 
13 import javax.servlet.ServletException;
14 import javax.servlet.http.HttpServlet;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletResponse;
17 
18 public class RoomServlet extends HttpServlet {
19 
20     private static final long serialVersionUID = 1L;
21 
22     private static final String RequestParamKey_Action = "action";
23     private static final String RequestAction_Create = "create";
24     private static final String RequestAction_Join = "join";
25     private static final String RequestAction_Quit = "quit";
26     private static final String RequestAction_GetList = "getList";
27     private static final String RequestAction_GetWatcher = "getWatcher";
28     private static final String RequestAction_HeartBeat = "heartBeat";
29 
30     // http://XXXX.com?action=create&userId=xxx&userAvatar=xxx&...
31     @Override
32     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
33             throws ServletException, IOException {
34         doGet(req, resp);
35     }
36 
37     @Override
38     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
39             throws ServletException, IOException {
40         // super.doGet(req, resp);
41         // 處理使用者的請求
42         String action = req.getParameter(RequestParamKey_Action);
43         if (action == null || "".equals(action)) {
44             ResponseObject responseObject = ResponseObject.getFailResponse(
45                     Error.errorCode_NoAction, Error.getNoActionMsg());
46             responseObject.send(resp);
47             return;
48         }
49         try {
50             if (RequestAction_Create.equals(action)) {
51                 // 建立一個直播房間。
52                 new CreateRoomAction().doAction(req, resp);
53             } else if (RequestAction_Join.equals(action)) {
54                 // 加入一個直播房間。
55                 new JoinRoomAction().doAction(req, resp);
56             } else if (RequestAction_Quit.equals(action)) {
57                 // 退出一個直播房間。
58                 new QuitRoomAction().doAction(req, resp);
59             } else if (RequestAction_GetList.equals(action)) {
60                 // 擷取直播房間清單。
61                 new GetRoomListAction().doAction(req, resp);
62             } else if (RequestAction_GetWatcher.equals(action)) {
63                 // 擷取房間中的觀衆
64                 new GetWatchersAction().doAction(req, resp);
65             } else if (RequestAction_HeartBeat.equals(action)) {
66                 // 心跳包
67                 new HeartBeatAction().doAction(req, resp);
68             } else {
69                 ResponseObject responseObject = ResponseObject.getFailResponse(
70                         Error.errorCode_NoRequestParam,
71                         Error.getNoRequestParamMsg(RequestParamKey_Action));
72                 responseObject.send(resp);
73             }
74         } catch (SQLException | IOException e) {
75             e.printStackTrace();
76             // 資料庫異常,傳回錯誤資訊
77             ResponseObject responseObject = ResponseObject.getFailResponse(
78                     Error.errorCode_Exception,
79                     Error.getExceptionMsg(e.getMessage()));
80             try {
81                 responseObject.send(resp);
82             } catch (IOException e1) {
83                 e1.printStackTrace();
84             }
85         }
86     }
87 
88 }      

4.2 優化2-sql的優化

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【封裝】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【‘最後的源碼】/ImoocBearLive/src/imooc/bear/live/SqlManager.java

1 package imooc.bear.live;
 2 
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.SQLException;
 6 
 7 //擷取資料庫連接配接的類
 8 public class SqlManager {
 9 
10     private static final String dbPro = "jdbc:mysql://";
11     private static final String host = "192.168.1.234";// ip位址
12     private static final String port = "30112";// 端口号
13     private static final String dbName = "5d4b8dd3c5be4";// 資料庫名字
14     private static final String charset = "?useUnicode=true&charactsetEncoding=utf-8";// 字元集
15 
16     private static final String url = dbPro + host + ":" + port + "/" + dbName
17             + charset;
18     private static final String user = "b3c15e03e3df4";
19     private static final String password = "d10ce1a25ae64";
20 
21     public static Connection getConnection() throws SQLException {
22         return DriverManager.getConnection(url, user, password);
23     }
24 
25 }      

【修改調用】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

5.擷取直播清單

5.1 架構的封裝

【擷取直播清單的邏輯】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【建立擷取清單的類】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【完善直播清單】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【封裝doGet】doget方法是所有的action需要的方法,是以需要抽象接口;

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【接口的實作】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【servlet的修改】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

5.2 直播清單的具體實作

【說明】【與資料庫互動】【進行下拉重新整理和上拉加載的功能】【分頁的功能】【需要設定多個參數】

【分頁頁面的擷取】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【錯誤碼的增加】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【錯誤資訊的傳回】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【從資料庫中擷取直播清單】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【異常的捕獲】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【測試】

【資料庫添加資料】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【資料包的導出】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【資料擷取】

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

6.直播房間清單界面實作--此段講解沒有完成

6.1 直播清單的布局

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【布局源碼】layout/fragment_live_list.xml

1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:id="@+id/activity_live_list"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7 
 8     <android.support.v7.widget.Toolbar
 9         android:id="@+id/titlebar"
10         android:layout_width="match_parent"
11         android:layout_height="?attr/actionBarSize"
12         android:background="@color/colorPrimaryDark" />
13 
14     <android.support.v4.widget.SwipeRefreshLayout
15         android:id="@+id/swipe_refresh_layout_list"
16         android:layout_width="match_parent"
17         android:layout_height="match_parent"
18         android:layout_below="@id/titlebar"
19         android:layout_weight="1">
20 
21         <ListView
22             android:id="@+id/live_list"
23             android:layout_width="match_parent"
24             android:layout_height="match_parent"
25             android:clickable="true"
26             android:divider="@null" />
27     </android.support.v4.widget.SwipeRefreshLayout>
28 
29 </RelativeLayout>      
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【item的源碼】

1 <?xml version="1.0" encoding="utf-8"?>
  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3     android:layout_width="match_parent"
  4     android:layout_height="wrap_content"
  5     android:orientation="vertical">
  6 
  7     <TextView
  8         android:id="@+id/live_title"
  9         android:layout_width="match_parent"
 10         android:layout_height="wrap_content"
 11         android:padding="15sp"
 12         android:text="标題"
 13         android:textColor="#333"
 14         android:textSize="18sp" />
 15 
 16     <View
 17         android:layout_width="match_parent"
 18         android:layout_height="1px"
 19         android:background="#3000" />
 20 
 21     <RelativeLayout
 22         android:id="@+id/live"
 23         android:layout_width="match_parent"
 24         android:layout_height="wrap_content">
 25 
 26         <ImageView
 27             android:id="@+id/live_cover"
 28             android:layout_width="match_parent"
 29             android:layout_height="210dp"
 30             android:scaleType="fitXY"
 31             android:src="@drawable/cover_background" />
 32 
 33         <ImageView
 34             android:id="@+id/live_logo"
 35             android:layout_width="wrap_content"
 36             android:layout_height="wrap_content"
 37             android:layout_alignParentRight="true"
 38             android:layout_alignParentTop="true"
 39             android:layout_marginRight="12dp"
 40             android:layout_marginTop="10dp"
 41             android:src="@drawable/icon_livewhite" />
 42 
 43         <LinearLayout
 44             android:id="@+id/host_bar"
 45             android:layout_width="match_parent"
 46             android:layout_height="55dp"
 47             android:background="#99efefef"
 48             android:layout_alignBottom="@+id/live_cover"
 49             android:orientation="horizontal">
 50 
 51             <ImageView
 52                 android:id="@+id/host_avatar"
 53                 android:layout_width="45dp"
 54                 android:layout_height="45dp"
 55                 android:layout_gravity="center_vertical"
 56                 android:layout_marginBottom="5dp"
 57                 android:layout_marginLeft="15dp"
 58                 android:layout_marginTop="5dp" />
 59 
 60             <LinearLayout
 61                 android:layout_width="0dp"
 62                 android:layout_height="wrap_content"
 63                 android:layout_gravity="center_vertical"
 64                 android:layout_marginLeft="15dp"
 65                 android:layout_weight="1"
 66                 android:orientation="vertical">
 67 
 68                 <TextView
 69                     android:id="@+id/host_name"
 70                     android:layout_width="wrap_content"
 71                     android:layout_height="wrap_content"
 72                     android:maxLines="1"
 73                     android:text="主播名字"
 74                     android:textColor="#333"
 75                     android:textSize="18sp" />
 76 
 77             </LinearLayout>
 78 
 79 
 80             <TextView
 81                 android:id="@+id/watch_nums"
 82                 android:layout_width="wrap_content"
 83                 android:layout_height="wrap_content"
 84                 android:layout_gravity="center"
 85                 android:layout_marginLeft="15dp"
 86                 android:layout_marginRight="15dp"
 87                 android:drawablePadding="5dp"
 88                 android:gravity="right"
 89                 android:text="1000\n在看"
 90                 android:textSize="14sp" />
 91 
 92         </LinearLayout>
 93 
 94     </RelativeLayout>
 95 
 96     <View
 97         android:layout_width="match_parent"
 98         android:layout_height="1dp"
 99         android:background="#3000" />
100 </LinearLayout>      
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

6.2 擴充卡的建立

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【源碼】imooc.com.bearlive.livelist.LiveListFragment

1 package imooc.com.bearlive.livelist;
  2 
  3 import android.content.Context;
  4 import android.content.Intent;
  5 import android.graphics.Color;
  6 import android.os.Bundle;
  7 import android.support.annotation.Nullable;
  8 import android.support.v4.app.Fragment;
  9 import android.support.v4.widget.SwipeRefreshLayout;
 10 import android.support.v7.app.AppCompatActivity;
 11 import android.support.v7.widget.Toolbar;
 12 import android.text.TextUtils;
 13 import android.view.LayoutInflater;
 14 import android.view.View;
 15 import android.view.ViewGroup;
 16 import android.widget.BaseAdapter;
 17 import android.widget.ImageView;
 18 import android.widget.ListView;
 19 import android.widget.TextView;
 20 import android.widget.Toast;
 21 
 22 import java.util.ArrayList;
 23 import java.util.List;
 24 
 25 import imooc.com.bearlive.R;
 26 import imooc.com.bearlive.model.RoomInfo;
 27 import imooc.com.bearlive.utils.ImgUtils;
 28 import imooc.com.bearlive.utils.request.BaseRequest;
 29 import imooc.com.bearlive.watcher.WatcherActivity;
 30 
 31 /**
 32  * Created by Administrator.
 33  */
 34 
 35 public class LiveListFragment extends Fragment {
 36 
 37     private ListView mLiveListView;
 38     private LiveListAdapter mLiveListAdapter;
 39     private SwipeRefreshLayout mSwipeRefreshLayout;
 40 
 41     @Nullable
 42     @Override
 43     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 44         super.onCreateView(inflater, container, savedInstanceState);
 45         View view = inflater.inflate(R.layout.fragment_live_list, container, false);
 46 
 47         findAllViews(view);
 48         requestLiveList();
 49 
 50         return view;
 51     }
 52 
 53     private void requestLiveList() {
 54         //請求前20個資料
 55         GetLiveListRequest liveListRequest = new GetLiveListRequest();
 56         liveListRequest.setOnResultListener(new BaseRequest.OnResultListener<List<RoomInfo>>() {
 57             @Override
 58             public void onSuccess(List<RoomInfo> roomInfos) {
 59 
 60                 mLiveListAdapter.removeAllRoomInfos();//下拉重新整理,先移除掉之前的room資訊
 61                 mLiveListAdapter.addRoomInfos(roomInfos);//再添加新的資訊
 62 
 63                 mSwipeRefreshLayout.setRefreshing(false);
 64             }
 65 
 66             @Override
 67             public void onFail(int code, String msg) {
 68                 Toast.makeText(getActivity(), "請求清單失敗:" + msg, Toast.LENGTH_SHORT).show();
 69                 mSwipeRefreshLayout.setRefreshing(false);
 70             }
 71         });
 72         GetLiveListRequest.LiveListParam param = new GetLiveListRequest.LiveListParam();
 73         param.pageIndex = 0;//從0開始,也就是第一頁。
 74         String url = liveListRequest.getUrl(param);
 75         liveListRequest.request(url);
 76     }
 77 
 78     private void findAllViews(View view) {
 79 
 80         Toolbar titlebar = (Toolbar) view.findViewById(R.id.titlebar);
 81         titlebar.setTitle("熱播清單");
 82         titlebar.setTitleTextColor(Color.WHITE);
 83         ((AppCompatActivity) getActivity()).setSupportActionBar(titlebar);
 84 
 85         mLiveListView = (ListView) view.findViewById(R.id.live_list);
 86         mLiveListAdapter = new LiveListAdapter(getContext());
 87         mLiveListView.setAdapter(mLiveListAdapter);
 88 
 89         mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout_list);
 90         mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 91             @Override
 92             public void onRefresh() {
 93                 //請求伺服器,擷取直播清單
 94                 requestLiveList();
 95             }
 96         });
 97     }
 98 
 99     private class LiveListAdapter extends BaseAdapter {
100 
101         private Context mContext;
102         private List<RoomInfo> liveRooms = new ArrayList<RoomInfo>();
103 
104         public LiveListAdapter(Context context) {
105             this.mContext = context;
106         }
107 
108         public void removeAllRoomInfos() {
109             liveRooms.clear();
110         }
111 
112         public void addRoomInfos(List<RoomInfo> roomInfos) {
113             if (roomInfos != null) {
114                 liveRooms.clear();
115                 liveRooms.addAll(roomInfos);
116                 notifyDataSetChanged();
117             }
118         }
119 
120         @Override
121         public int getCount() {
122             return liveRooms.size();
123         }
124 
125         @Override
126         public RoomInfo getItem(int position) {
127             return liveRooms.get(position);
128         }
129 
130         @Override
131         public long getItemId(int position) {
132             return position;
133         }
134 
135         @Override
136         public View getView(int position, View convertView, ViewGroup parent) {
137             RoomHolder holder = null;
138             if (convertView == null) {
139                 convertView = LayoutInflater.from(mContext).inflate(R.layout.item_live_list, null);
140                 holder = new RoomHolder(convertView);
141                 convertView.setTag(holder);
142             } else {
143                 holder = (RoomHolder) convertView.getTag();
144             }
145 
146             holder.bindData(liveRooms.get(position));
147 
148             return convertView;
149         }
150 
151 
152         private class RoomHolder {
153 
154             View itemView;
155             TextView liveTitle;
156             ImageView liveCover;
157             ImageView hostAvatar;
158             TextView hostName;
159             TextView watchNums;
160 
161             public RoomHolder(View view) {
162                 itemView = view;
163                 liveTitle = (TextView) view.findViewById(R.id.live_title);
164                 liveCover = (ImageView) view.findViewById(R.id.live_cover);
165                 hostName = (TextView) view.findViewById(R.id.host_name);
166                 hostAvatar = (ImageView) view.findViewById(R.id.host_avatar);
167                 watchNums = (TextView) view.findViewById(R.id.watch_nums);
168             }
169 
170             public void bindData(final RoomInfo roomInfo) {
171 
172                 String userName = roomInfo.userName;
173                 if (TextUtils.isEmpty(userName)) {
174                     userName = roomInfo.userId;
175                 }
176                 hostName.setText(userName);
177 
178                 String liveTitleStr = roomInfo.liveTitle;
179                 if (TextUtils.isEmpty(liveTitleStr)) {
180                     this.liveTitle.setText(userName + "的直播");
181                 } else {
182                     this.liveTitle.setText(liveTitleStr);
183                 }
184                 String url = roomInfo.liveCover;
185                 if (TextUtils.isEmpty(url)) {
186                     ImgUtils.load(R.drawable.default_cover, liveCover);
187                 } else {
188                     ImgUtils.load(url, liveCover);
189                 }
190 
191                 String avatar = roomInfo.userAvatar;
192                 if (TextUtils.isEmpty(avatar)) {
193                     ImgUtils.loadRound(R.drawable.default_avatar, hostAvatar);
194                 } else {
195                     ImgUtils.loadRound(avatar, hostAvatar);
196                 }
197 
198                 int watchers = roomInfo.watcherNums;
199                 String watchText = watchers + "人\r\n正在看";
200                 watchNums.setText(watchText);
201 
202                 itemView.setOnClickListener(new View.OnClickListener() {
203                     @Override
204                     public void onClick(View view) {
205                         Intent intent = new Intent();
206                         intent.setClass(mContext, WatcherActivity.class);
207                         intent.putExtra("roomId", roomInfo.roomId);
208                         intent.putExtra("hostId", roomInfo.userId);
209                         startActivity(intent);
210                     }
211                 });
212             }
213         }
214     }
215 }      

7.主播直播的基本界面

【說明】用到了主播直播的騰訊雲中的主播開直播的功能

【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發

【布局】

1 <?xml version="1.0" encoding="utf-8"?>
 2 <imooc.com.bearlive.widget.SizeChangeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:id="@+id/size_change_layout"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context="imooc.com.bearlive.hostlive.HostLiveActivity">
 8 
 9 
10     <com.tencent.ilivesdk.view.AVRootView
11         android:id="@+id/live_view"
12         android:layout_width="match_parent"
13         android:layout_height="match_parent"
14         android:background="@android:color/white" />
15 
16     <imooc.com.bearlive.view.TitleView
17         android:id="@+id/title_view"
18         android:layout_width="match_parent"
19         android:layout_height="wrap_content" />
20 
21     <FrameLayout
22         android:id="@+id/bottom_view"
23         android:layout_width="match_parent"
24         android:layout_height="wrap_content"
25         android:layout_alignParentBottom="true">
26 
27         <imooc.com.bearlive.view.BottomControlView
28             android:id="@+id/control_view"
29             android:layout_width="match_parent"
30             android:layout_height="wrap_content" />
31 
32         <imooc.com.bearlive.view.ChatView
33             android:id="@+id/chat_view"
34             android:layout_width="match_parent"
35             android:layout_height="wrap_content" />
36     </FrameLayout>
37 
38     <LinearLayout
39         android:id="@+id/chat_list_view"
40         android:layout_width="match_parent"
41         android:layout_height="wrap_content"
42         android:layout_above="@id/bottom_view"
43         android:orientation="horizontal">
44 
45         <imooc.com.bearlive.view.ChatMsgListView
46             android:id="@+id/chat_list"
47             android:layout_width="0dp"
48             android:layout_height="180dp"
49             android:layout_weight="2" />
50 
51         <View
52             android:layout_width="0dp"
53             android:layout_height="200dp"
54             android:layout_weight="1" />
55     </LinearLayout>
56     <imooc.com.bearlive.view.VipEnterView
57         android:id="@+id/vip_enter"
58         android:layout_width="wrap_content"
59         android:layout_height="wrap_content"
60         android:layout_above="@id/chat_list_view" />
61     <tyrantgit.widget.HeartLayout
62         android:id="@+id/heart_layout"
63         android:layout_width="100dp"
64         android:layout_height="match_parent"
65         android:layout_alignParentRight="true" />
66 
67     <imooc.com.bearlive.view.DanmuView
68         android:id="@+id/danmu_view"
69         android:layout_width="match_parent"
70         android:layout_height="wrap_content"
71         android:layout_above="@id/vip_enter" />
72 
73     <imooc.com.bearlive.view.GiftRepeatView
74         android:id="@+id/gift_repeat_view"
75         android:layout_width="wrap_content"
76         android:layout_height="match_parent"
77         android:layout_above="@id/chat_list_view" />
78 
79     <imooc.com.bearlive.view.GiftFullView
80         android:id="@+id/gift_full_view"
81         android:layout_width="match_parent"
82         android:layout_height="match_parent" />
83 </imooc.com.bearlive.widget.SizeChangeRelativeLayout>      
【0101】【項目實戰】-【Android互動直播APP開發】-【4】直播APP服務端接口開發