天天看点

【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服务端接口开发