黎活明8天快速掌握android视频教程--25_网络通信之资讯客户端
1 该项目的主要功能是:后台通过xml或者json格式返回后台的视频资讯,然后Android客户端界面显示出来
首先后台新建立一个java web后台
采用mvc的框架
所以的servlet都放在servlet中,servlet想当于android中的controller层,android中的控制层下面可以在分为activity 、fragment和adapter 、serverce服务和broadcast广播
Service是业务层,按照面向接口编程的原则,控制层的数据不能直接和业务层的实现类打交道,只能和业务层的具体实现类打交道,这里service就是业务层的业务接口,定义了业务操作的接口
Service.impl
这里就是业务接口的具体实现类,在这里通过调研数据库model模型层的数据接口访问数据库,在这里业务实现类也不能直接访问数据量,而是通过model层提供的数据库接口才能操作数据库。
Model数据库模型层,里面又可以分为db、dao,model层主要通过单例;提供一个数据库访问的接口提供给业务层的实现类调用。
例如:在这里通过数据库的接口操作数据库 Model.getInstace().getVideoNewsDao(),通过这种方式通过model层提供一个接口让业务库实现类调用,最好不要使用直接new VideoNewsDao()的方式
bean
就是存储具体的java对象
我们来看下后台的代码:
package com.videonews.bean; public class VideoNewsBean {
private Integer videoId ;//电影id
private String videoTitle ;// 电影标题
private Integer timeLength ;//电影时间长度 public VideoNewsBean() {
super();
}
public VideoNewsBean(Integer videoId, String videoTitle, Integer timeLength) {
this.videoId = videoId;
this.videoTitle = videoTitle;
this.timeLength = timeLength;
}
public Integer getVideoId() {
return videoId;
}
public void setVideoId(Integer videoId) {
this.videoId = videoId;
}
public String getVideoTitle() {
return videoTitle;
}
public void setVideoTitle(String videoTitle) {
this.videoTitle = videoTitle;
}
public Integer getTimeLength() {
return timeLength;
}
public void setTimeLength(Integer timeLength) {
this.timeLength = timeLength;
}
@Override
public String toString() {
return "VideoNewsBean [videoId=" + videoId + ", videoTitle="
+ videoTitle + ", timeLength=" + timeLength + "]";
} }
我们来看业务的实现接口:
package com.videonews.service; import java.util.List; import com.videonews.bean.VideoNewsBean; public interface VideoNewsService { public List<VideoNewsBean> getAllNews();
}
我们来看业务接口的实现类:
public class VideoNewsServiceImp implements VideoNewsService { @Override
public List<VideoNewsBean> getAllNews() throws Exception{
// TODO Auto-generated method stub //在这里通过数据库的接口操作数据库 Model.getInstace().getVideoNewsDao() //这里我们操作数据库,我们直接模拟数据
List<VideoNewsBean> datas = new ArrayList<VideoNewsBean>();
datas.add(new VideoNewsBean(1, "人民的利益", 100));
datas.add(new VideoNewsBean(2, "三生三世", 100));
datas.add(new VideoNewsBean(1, "光头强", 100));
return datas;
}
正常的业务操作中:业务实现类应该通过数据库接口操作数据库获得对象的数据,这里我们模拟该过程直接返回数据
我们来看看
ListServlet:
public class ListServlet extends HttpServlet {
VideoNewsService service = new VideoNewsServiceImp(); //采用面向接口的编程方式,控制层只能和业务类的接口打交道,最好不要写成 public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//判断是返回json,还是返回xml格式的数据
String format = (String) request.getAttribute("format");
if(format == null || "json".equals(format)){
//进行业务操作获得数据
try {
List<VideoNewsBean> news = service.getAllNews(); //封装json字符串数据
//1 方法1 使用第三方的gson框架,这里使用Gson,需要gson的jar包
Gson gson = new Gson();
String jsonString = gson.toJson(news);
//方法2自己封装json字符串数据,在实际的开发过程中当然使用gson框架
//[{"videoId":1,"videoTitle":"人民的利益","timeLength":100},{"videoId":2,"videoTitle":"三生三世","timeLength":100},
//{"videoId":1,"videoTitle":"光头强","timeLength":100}]
// "使用转义写成\",{直接写成"{"
StringBuilder builder = new StringBuilder();
builder.append("[");
for(VideoNewsBean videonew:news){
builder.append("{").append("\"");
builder.append("videoId").append("\"").append(":").append(""+videonew.getVideoId()).append(";");
builder.append("videoTitle").append("\"").append(":").append(""+videonew.getVideoTitle()).append(";");
builder.append("timeLength").append("\"").append(":").append(""+videonew.getTimeLength()).append("}");
builder.append(","); }
//遍历之后最后多了一个builder.append(",");要记得去掉
builder.deleteCharAt(builder.length()-1);
builder.append("]");
String jsonString2 = builder.toString(); request.setAttribute("json", jsonString);
//重定向到jsp页面
request.getRequestDispatcher("WEB-INF/page/json.jsp").forward(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//业务操作失败,需要在界面jsp上面提示用户,或者对业务操作失败做出其他的处理
}
}else{
//进行业务操作获得数据
try {
List<VideoNewsBean> news = service.getAllNews();
request.setAttribute("videos", news);
//重定向到jsp页面
request.getRequestDispatcher("WEB-INF/page/videonews.jsp").forward(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//业务操作失败,需要在界面jsp上面提示用户,或者对业务操作失败做出其他的处理
} } } }
上面有几个地方需要注意的:
控制层和业务层采用面向接口的编程方式,控制层只和业务的接口类打交道
VideoNewsService service = new VideoNewsServiceImp();
而不是具体和业务的实现类打交道,最好不需写成 VideoNewsServiceImp service = new VideoNewsServiceImp();
2、依据客户端请求的客户觉得是以xml的格式还是json的格式返回数据给客户端
3、同理业务库实现类也不能直接操作数据库,必须通过数据库的接口操作数据库Model.getInstance.getVideoNewsDao();通过model模型层提供一个操作数据库的接口访问数据库,这就是面向接口的编程的思想。这里模拟操作数据库的过程直接将数据返回业务类
4、在进行业务操作的时候getAllNews()如果这个业务操作有异常,应该将异常抛出,不应该内存try catch进行处理,而应该抛出给控制层servlet。Servlet已经异常才知道该业务操作是成功还是失败,在jsp或者html中进行显示。
5、我们来看看web-inf/page/videonews.jsp的代码:如果以xml的方法返回给客户端
<%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><?xml version="1.0" encoding="UTF-8"?>
<videonews><c:forEach items="${videos}" var ="video">
<news id = "${video.videoId}">
<title>${video.videoTitle}</title>
<timelength>${video.timeLength}</timelength>
</news></c:forEach>
</videonews>
上面使用了jsp的c标签进行遍历,需要在java web工程的libs目录下添加下面两个jar包,并且
contentType="text/xml;必须是xml格式
我们在浏览器上访问:
现在我们在浏览器访问http://localhost:8080/lihuoming_25/ListServlet
如果是以json格式返回,videonews.jsp的代码如下:
<%@ page language="java" contentType="text/plain; charset=utf-8"
pageEncoding="utf-8"%>
${json}
我们来看看整个java web工程的程序框架是:
我们来看看Android端客户端的代码:
客户端也是按照后台一样采用mvc的框架
也是采用控制层、模型层、业务层、工具类类型的四种方式
控制层包括activity 、fargment 、receiver等
业务层:主要进行业务操作,例如从服务器上或者接送数据,业务层的异常最好不要使用try catch内部处理,而已经将异常抛出,在控制层处理异常,如果控制层可以通过异常知道业务操作是否成功,在界面上做出相应的显示
业务层最好写成业务接口类类和业务实现类:接口主要定义业务的具有方法,实现类主要实现该业务的具体操作
Model:主要操作数据库,封装数据库操作的接口提供给业务层调用例如Model.getInstance.getDbDao()采用单例的模式提供一个数据库接口给业务实现类调用,不清楚的可以看尚硅谷硅谷社交项目。
Bean:封装Javabean对象
Utils工具类主要工具类。
我们首先来看业务的接口类:
package application.weiyuan.com.lihuoming_25.bussiness; import org.json.JSONException;
import org.xmlpull.v1.XmlPullParserException; import java.io.IOException;
import java.util.List; import application.weiyuan.com.lihuoming_25.model.bean.VideoNewsBean; /**
* Created by wei.yuan on 2017/4/24.
*/ public interface VideoNewsService {
public List<VideoNewsBean> getAllNews(String path) throws IOException, XmlPullParserException, JSONException;
}
我们来看业务的实现类:
import android.util.Log;
import android.util.Xml; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List; import javax.xml.datatype.XMLGregorianCalendar; import application.weiyuan.com.lihuoming_25.model.bean.VideoNewsBean; /**
* Created by Administrator on 2017/4/18.
*
XmlPullParser.START_DOCUMENT对应文档开始
XmlPullParser.END_DOCUMENT
<videnews>是根元素、有三个<News>子元素
<标记名称 属性名1="属性值1" 属性名1="属性值1" ……>内容</标记名称>
起始标签(外国语:starttag)表示一个特定区域的开始,例如<起始>;
结束标签(外国语:end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</结束>;
其中标记名称对应的事件是XmlPullParser.START_TAG ,<news>或者<title>都是一个开始tag
</news>对应一个XmlPullParser.END_TAG
<news id =”2”>其中id就是这个tag的属性
<title>光头强</title>这个tag标签没有属性,但是存在内容,内容就是光头强
注意根元素<videnews>也是一个tag标签,我们通过程序的代码日志打印就可以看出来 04-19 00:19:06.508 10100-10138/? D/123456 start_tag: videonews
04-19 00:19:06.508 10100-10138/? D/123456 start_tag: news
04-19 00:19:06.508 10100-10138/? D/123456 start_tag: title
04-19 00:19:06.509 10100-10138/? D/123456 start_tag: timelength
04-19 00:19:06.509 10100-10138/? D/123456 end_tag: news
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: news
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: title
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: timelength
04-19 00:19:06.510 10100-10138/? D/123456 end_tag: news
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: news
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: title
04-19 00:19:06.510 10100-10138/? D/123456 start_tag: timelength
04-19 00:19:06.510 10100-10138/? D/123456 end_tag: news
04-19 00:19:06.510 10100-10138/? D/123456 end_tag: videonews
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: videonews
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/? D/123456 end_tag: news
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/? D/123456 end_tag: news
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/? D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/? D/123456 end_tag: news
04-19 00:19:11.493 10370-10387/? D/123456 end_tag: videonews */
public class VideoNewsServiceImp implements VideoNewsService{ public List<VideoNewsBean> getAllNews(String path) throws IOException, XmlPullParserException, JSONException {
List<VideoNewsBean> news = new ArrayList<>();
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.connect();
if(connection.getResponseCode() == 200){
InputStream inputStream = connection.getInputStream();
//news = pullXML(inputStream);//服务器返回的xml格式
news = pullJson(inputStream); //返回的json字符串
}
return news;
} //对xml文件进行解析
public List<VideoNewsBean> pullXML(InputStream in) throws XmlPullParserException, IOException {
List<VideoNewsBean> datas = null;
VideoNewsBean newsBean = null;
XmlPullParser pullParser = Xml.newPullParser(); //获得一个xml的pull解析器
pullParser.setInput(in, "utf-8"); //设置解析的编码格式,必须和服务器段的jsp中的xml编码格式对象
int eventType = pullParser.getEventType(); //开启一个解析事件
while (eventType != XmlPullParser.END_DOCUMENT){ //只要事件不是xml的文档结束事件,就一直解析,
//XmlPullParser.END_DOCUMENT表示xml已经解析完成了
switch (eventType){
case XmlPullParser.START_DOCUMENT: //开启文档解析事件
datas = new ArrayList<>();
break;
case XmlPullParser.START_TAG: // 开始一个标签的解析
Log.d("123456 start_tag",pullParser.getName());
if(pullParser.getName().equals("news")){
newsBean = new VideoNewsBean();
//获得标签的属性值
int id = Integer.parseInt(pullParser.getAttributeValue(0));//0表示第一个属性,如果是1表示第二个属性值
newsBean.setVideoId(id);
break; }else if(pullParser.getName().equals("title")){
//获得titile的内容
// <title>人民的利益</title>,解析分为三个事件<title>是标签开始事件 人民的利益是标签的内容为第二个事件,
// </title>为第三个事件
//现在解析到了<title>,pullParser.next()就是到下一个事件 pullParser.nextText()下一个事件的文本值
String title = pullParser.nextText();
newsBean.setVideoTitle(title);
break; }else if(pullParser.getName().equals("timelength")){
int timeLength = Integer.parseInt(pullParser.nextText());
newsBean.setTimeLength(timeLength);
break; }else {
break;
}
case XmlPullParser.END_TAG: //一个标签解析完成
Log.d("123456 end_tag",pullParser.getName());
if(pullParser.getName().equals("news")){
datas.add(newsBean);
newsBean = null;
}
break;
case XmlPullParser.END_DOCUMENT: //结束文档解析事件
return datas;
}
//解析下一个事件
eventType = pullParser.next(); } return datas;
} //对服务器返回的json数据进行解析
public List<VideoNewsBean> pullJson(InputStream in) throws IOException, JSONException {
List<VideoNewsBean> news = new ArrayList<>();
//第一步将InputStream转化成byte[]
byte[] buffer= new byte[1024];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int len = -1;
while ((len = in.read(buffer))!= -1){
outputStream.write(buffer,0,len);
}
byte[] bytes = outputStream.toByteArray(); String jsonString = new String(bytes,"utf-8");//编码必须和服务器的一样
//第二步将byte转化成json数组
JSONArray jsonArray = new JSONArray(jsonString);
//获得json数组中的jsonObject对象
for(int i = 0 ;i < jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
VideoNewsBean bean = new VideoNewsBean();
bean.setVideoId(jsonObject.getInt("videoId"));
bean.setVideoTitle(jsonObject.getString("videoTitle"));
bean.setTimeLength(jsonObject.getInt("timeLength"));
news.add(bean);
} return news;
}
}
对xml解析比较复杂:
XML元素与HTML元素的格式基本相同,其格式如下:
<标记名称 属性名1="属性值1" 属性名1="属性值1" ……>内容</标记名称>
所有的数据内容都必须在某个标记的开始和结束标记内,而每个标记又必须包含在另一个标记的开始与结束标记内,形成嵌套式的分布,只有最外层的标记不必被其他的标记所包含。最外层的是根元素(Root),又称文件(Document)元素,所有的元素都包含在根元素内。在前面的Flowers.xml文件中,根元素就是<Flowers>,根元素必须而且只能有一个,在该文件有三个<Flower>子元素,这样的元素可以有多个。
XmlPullParser.START_DOCUMENT对应文档开始
XmlPullParser.END_DOCUMENT
<videnews>是根元素、有三个<News>子元素
<标记名称 属性名1="属性值1" 属性名1="属性值1" ……>内容</标记名称>
起始标签(外国语:starttag)表示一个特定区域的开始,例如<起始>;
结束标签(外国语:end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</结束>;
其中标记名称对应的事件是XmlPullParser.START_TAG ,<news>或者<title>都是一个开始tag
</news>对应一个XmlPullParser.END_TAG
<news id =”2”>其中id就是这个tag的属性
<title>光头强</title>这个tag标签没有属性,但是存在内容,内容就是光头强
注意根元素<videnews>也是一个tag标签,我们通过程序的代码日志打印就可以看出来
04-19 00:19:06.508 10100-10138/? D/123456 start_tag: videonews
04-19 00:19:06.508 10100-10138/?
D/123456 start_tag: news
04-19 00:19:06.508 10100-10138/?
D/123456 start_tag: title
04-19 00:19:06.509 10100-10138/?
D/123456 start_tag: timelength
04-19 00:19:06.509 10100-10138/?
D/123456 end_tag: news
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: news
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: title
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: timelength
04-19 00:19:06.510 10100-10138/?
D/123456 end_tag: news
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: news
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: title
04-19 00:19:06.510 10100-10138/?
D/123456 start_tag: timelength
04-19 00:19:06.510 10100-10138/? D/123456
end_tag: news
04-19 00:19:06.510 10100-10138/?
D/123456 end_tag: videonews
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: videonews
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/?
D/123456 end_tag: news
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/?
D/123456 end_tag: news
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: news
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: title
04-19 00:19:11.492 10370-10387/?
D/123456 start_tag: timelength
04-19 00:19:11.492 10370-10387/?
D/123456 end_tag: news
04-19 00:19:11.493 10370-10387/?
D/123456 end_tag: videonews
我们来看activity的代码:
public class MainActivity extends Activity { private ListView lv_main;
private VideoNewsService service = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
} private void initData() {
service = new VideoNewsServiceImp();
final String path = "http://192.168.1.103:8080/lihuoming_25/ListServlet";
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
try {
final List<VideoNewsBean> news = service.getAllNews(path);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"" +
"获得数据成功"+news.size(),Toast.LENGTH_SHORT).show();
List<Map<String, String>> listems = new ArrayList<Map<String, String>>();
for (int i = 0; i < news.size(); i++) {
VideoNewsBean newsBean = news.get(i);
Map<String, String> listem = new HashMap<String, String>();
listem.put("id", newsBean.getVideoId()+"");
listem.put("title", newsBean.getVideoTitle()+"");
listem.put("timeLength", newsBean.getTimeLength()+"");
listems.add(listem);
}
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, listems,
R.layout.item_news, new String[] {"title", "timeLength" },
new int[] {R.id.name,R.id.desc});
lv_main.setAdapter(adapter); /*SimpleAdapter的参数说明
* 第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要
* 第二个参数表示生成一个Map(String ,Object)列表选项
* 第三个参数表示界面布局的id 表示该文件作为列表项的组件
* 第四个参数表示该Map对象的哪些key对应value来生成列表项
* 第五个参数表示来填充的组件 Map对象key对应的资源一依次填充组件 顺序有对应关系
* 注意的是map对象可以key可以找不到 但组件的必须要有资源填充 因为 找不到key也会返回null 其实就相当于给了一个null资源
* 下面的程序中如果 new String[] { "name", "head", "desc","name" } new int[] {R.id.name,R.id.head,R.id.desc,R.id.head}
* 这个head的组件会被name资源覆盖
* */ }
});
} catch (final Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,"" +
"获得数据失败"+e.toString(),Toast.LENGTH_SHORT).show();
}
});
}
}
}); } private void initView() {
lv_main = (ListView) findViewById(R.id.lv_main);
}
}
我们来看xml布局文件:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="application.weiyuan.com.lihuoming_25.MainActivity">
<ListView
android:id="@+id/lv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"> </ListView> </RelativeLayout>
item_news.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="horizontal" > <TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="#f0f"
android:paddingLeft="10dp"/> <TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dp"
android:paddingLeft="10dp"/> </LinearLayout>
黎活明8天快速掌握android视频教程--25_网络通信之资讯客户端的更多相关文章
- 黎活明8天快速掌握android视频教程--24_网络通信之网页源码查看器
1 该项目的主要功能就是从将后台的html网页在Android的界面上显示出来 后台就是建立一个java web工程在工程尚建立一个html或者jsp文件就可以了,这里主要看Android客户端的程序 ...
- 黎活明8天快速掌握android视频教程--23_网络通信之网络图片查看器
1.首先新建立一个java web项目的工程.使用的是myeclipe开发软件 图片的下载路径是http://192.168.1.103:8080/lihuoming_23/3.png 当前手机和电脑 ...
- 黎活明8天快速掌握android视频教程--27_网络通信之通过GET和POST方式提交参数给web应用
1该项目主要实现Android客户端以get的方式或者post的方式向java web服务器提交参数 Android客户端通过get方式或者post方式将参数提交给后台服务器,后台服务器对收到的参数进 ...
- 黎活明8天快速掌握android视频教程--22_访问通信录中的联系人和添加联系人
Android系统中联系人的通讯录的contentProvide是一个单独的apk,显示在界面的contact也是一个独立的apk,联系人apk通过contentProvide访问底层的数据库. 现在 ...
- 黎活明8天快速掌握android视频教程--21_监听ContentProvider中数据的变化
采用ContentProvider除了可以让其他应用访问当前的app的数据之外,还有可以实现当app的数据发送变化的时候,通知注册了数据变化通知的调用者 其他所有的代码都和第20讲的一样,不同的地方看 ...
- 黎活明8天快速掌握android视频教程--20_采用ContentProvider对外共享数据
1.内容提供者是让当前的app的数据可以让其他应用访问,其他应该可以通过内容提供者访问当前app的数据库 contentProvider的主要目的是提供一个开发的接口,让其他的应该能够访问当前应用的数 ...
- 黎活明8天快速掌握android视频教程--19_采用ListView实现数据列表显示
1.首先整个程序也是采用mvc的框架 DbOpenHelper 类 package dB; import android.content.Context; import android.databas ...
- 黎活明8天快速掌握android视频教程--17_创建数据库与完成数据添删改查
1.我们首先来看下整个项目 项目也是采用mvc的框架 package dB; import android.content.Context; import android.database.sqlit ...
- 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数
SharedPreferences保存的数据是xml格式,也是存在数据保存的下面四种权限: 我们来看看 我们来看看具体的业务操作类: /** * 文件名:SharedPrecences.java * ...
随机推荐
- [工具推荐]005.Axure RP Pro 7.0模拟C#TAB控件
有一次,主管安排我写一个项目的原型,但是项目中涉及到了Tab控件,在Axure中的控件中找了一番,没有找着Tab控件.那么我们只能换种法子来实现它了,我们用到了Dynamic Panel来模拟. 1. ...
- STM32与匿名上位机通信——使用串口DMA实现
背景:匿名上位机功能强大,这里想要采用匿名上位机输出一些调试信息,以波形的形式显示,方便观察和调试. 平台: 硬件:STM32F405RGT6 通信:2.4G zigbee无线串口收发模块 CC253 ...
- 05 . 前端之BootStrap
BootStrap简介 Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍的前端开 ...
- [前端开发]form-data和x-www-form-urlencoded的区别
在后台开发时,之前做了文件的上传,用的是form-data,但并不知其区别.今天遇到了req.body为空的情况,切换成了x-www-form-urlencoded解决 form-data 就是htt ...
- 学习源码的第八个月,我成了Spring的开源贡献者
@ 目录 我的经历 碰到的问题 1.担心闹乌龙 2.不知道要怎么提交 3.英文 4.担心问题描述的不清楚 给你的建议 我的经历 关注我的朋友都知道,关注两个字划重点,要考! 我最近一直在写Spring ...
- ActiveMQ 笔记(八)高级特性和大厂常考重点
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.可用性保证 引入消息队列之后该如何保证其高可用性? 持久化.事务.签收. 以及带复制的 Leavel ...
- JAVASE(十一) 高级类特性: abstract 、模板模式、interface、内部类、枚举、注解
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.关键字 abstract 1.1.abstract可以修饰:类,方法 1.2.abstract修饰方 ...
- Java实现 LeetCode 718 最长重复子数组(动态规划)
718. 最长重复子数组 给两个整数数组 A 和 B ,返回两个数组中公共的.长度最长的子数组的长度. 示例 1: 输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释 ...
- Java实现 LeetCode 677 键值映射(字典树)
677. 键值映射 实现一个 MapSum 类里的两个方法,insert 和 sum. 对于方法 insert,你将得到一对(字符串,整数)的键值对.字符串表示键,整数表示值.如果键已经存在,那么原来 ...
- Java实现 蓝桥杯 算法训练 关联矩阵
算法训练 关联矩阵 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 有一个n个结点m条边的有向图,请输出他的关联矩阵. 输入格式 第一行两个整数n.m,表示图中结点和边的数目.n&l ...