要做一个优秀的Android应用,使用到网络通信技术是必不可少的,很难想象一款没有网络交互的软件最终能发展得多成功。那么我们来看一下,一般Android应用程序里都是怎么实现网络交互的,这里拿一个Boook对象为例:
如上图所示,首先在手机端生成一个Book对象,里面包含书名、作者、价格等数据。为了要将这些数据发送到服务器端,我们要从Book对象中把数据取出,然后组装成XML格式的字符串。接着通过网络API,把组装好的XML字符串发送到服务器端。服务器端接到了客户端发来的XML字符串,就要对该XML进行解析。然后把解析出的数据重新组装成Book对象,之后服务器端就可以对该对象进行一系列其它的操作了。
当然XML格式的数据量比较大,现在很多Android应用为了节省流量,都改用JSON格式来传输数据了。不过不管是使用XML还是JSON,上图中描述的步骤总是少不了的。
感觉使用这种方式来传输数据,每次封装和解析XML的过程是最繁琐的,那么能不能把这最繁琐的过程绕过去呢?
如上图所示,如果可以调用网络API,直接把Book对象发送到服务器端,那么整个网络交互过程就会变得非常简单,下面我们就来看看如何实现。
新建一个Android工程,命名为ClientTest作为客户端工程。这里第一个要确定的就是待传输的对象,我们新建一个Book类,代码如下:
- package com.test;
- import java.io.Serializable;
- public class Book implements Serializable {
- private String bookName;
- private String author;
- private double price;
- private int pages;
- public String getBookName() {
- return bookName;
- }
- public void setBookName(String bookName) {
- this.bookName = bookName;
- }
- public String getAuthor() {
- return author;
- }
- public void setAuthor(String author) {
- this.author = author;
- }
- public double getPrice() {
- return price;
- }
- public void setPrice(double price) {
- this.price = price;
- }
- public int getPages() {
- return pages;
- }
- public void setPages(int pages) {
- this.pages = pages;
- }
- }
接下来打开或新建activity_main.xml作为程序的主布局文件,加入如下代码:
- <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:background="#000"
- tools:context=".MainActivity" >
- <Button
- android:id="@+id/send"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="发送"
- />
- </RelativeLayout>
接下来打开或新建MainActivity作为程序的主Activity,其中加入如下代码:
- public class MainActivity extends Activity implements OnClickListener {
- private Button send;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- send = (Button) findViewById(R.id.send);
- send.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- Book book = new Book();
- book.setBookName("Android高级编程");
- book.setAuthor("Reto Meier");
- book.setPages(398);
- book.setPrice(59.00);
- URL url = null;
- ObjectOutputStream oos = null;
- try {
- url = new URL("http://192.168.1.103:8080/ServerTest/servlet/TestServlet");
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setDoInput(true);
- connection.setDoOutput(true);
- connection.setConnectTimeout(10000);
- connection.setReadTimeout(10000);
- connection.setRequestMethod("POST");
- oos = new ObjectOutputStream(connection.getOutputStream());
- oos.writeObject(book);
- InputStreamReader read = new InputStreamReader(connection.getInputStream());
- BufferedReader br = new BufferedReader(read);
- String line = "";
- while ((line = br.readLine()) != null) {
- Log.d("TAG", "line is " + line);
- }
- br.close();
- connection.disconnect();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- }
- }
- }
注意由于我们使用了网络功能,因此需要在AndroidManifest.xml中加入如下权限:
- <uses-permission android:name="android.permission.INTERNET" />
新建一个名为ServerTest的Web Project,要做的第一件事就在Web Project下建立一个和Android端一样的Book类。这里有个非常重要的点大家一定要注意,服务器端的Book类和Android端的Book类,包名和类名都必须相同,否则会出现类型转换异常。这里由于两个Book类的内容是完全一样的,我就不再重复贴出。
然后新建一个Java Servlet作为网络访问接口,我们重写它的doPost方法,具体代码如下:
- public class TestServlet extends HttpServlet {
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- ObjectInputStream ois = null;
- try {
- ois = new ObjectInputStream(request.getInputStream());
- Book book = (Book) ois.readObject();
- System.out.println("书名是: " + book.getBookName());
- System.out.println("作者是: " + book.getAuthor());
- System.out.println("价格是: " + book.getPrice());
- System.out.println("页数是: " + book.getPages());
- PrintWriter out = response.getWriter();
- out.print("success");
- out.flush();
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- ois.close();
- }
- }
- }
现在我们来运行一下程序,首先将ServerTest这个项目布置到服务器上,并开启服务器待命。接着在手机上打开ClientTest这个应用程序,如下图所示:
点击发送发出网络请求,可以看到服务器端打印结果如下:
而Android端打印结果如下:
由此我们可以看出,网络上进行对象传输已经成功了!不需要通过繁琐的XML封装和解析,我们也成功将Book中的数据完整地从Android端发送到了服务器端。
package com.vtion.sleb.banca.http;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.db4o.ObjectContainer;
import com.db4o.ext.DatabaseClosedException;
import com.db4o.ext.DatabaseReadOnlyException;
import com.db4o.ext.Db4oIOException;
import com.vtion.sleb.activities.R;
import com.vtion.sleb.banca.model.AdvertItem;
import com.vtion.sleb.banca.utils.SDUtils;
import com.vtion.sleb.entity.FileMsg;
public class FindAdByNameHttpClient extends Thread {
private static final int REFRESHAD = 0x124;
private Context context;
private Handler handler;
private List<FileMsg> fileMsgList;
private ObjectContainer db;
public FindAdByNameHttpClient(Context context, Handler handler, List<FileMsg> fileMsgList, ObjectContainer db) {
super();
this.context = context;
this.handler = handler;
this.fileMsgList = fileMsgList;
this.db = db;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
if (!SDUtils.checkSD())
return;
try {
int index = 0;
for (FileMsg e : fileMsgList) {
index = fileMsgList.indexOf(e);
String findAdByNameurl = context.getResources().getString(R.string.SERVER_URL) + "client/findAdByName.do?fileName=" + e.getFileId();
URL getUrl = new URL(findAdByNameurl);
HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
connection.setRequestProperty("Accept-Charset", "utf-8");
connection.setRequestProperty("contentType", "utf-8");
connection.setRequestMethod("POST");
connection.setConnectTimeout(15 * 1000);
connection.setReadTimeout(15 * 1000);
connection.connect();
int responseCode = connection.getResponseCode();
// 服务器响应OK 状态吗=200
if (responseCode == 200) {
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream((connection.getInputStream())));
FileMsg fileMsg = (FileMsg) objectIn.readObject();
objectIn.close();
if (fileMsg == null)
return;
byte[] bytes = fileMsg.getImageFile(); // 得到图片的字节数据
String sdDir = Environment.getExternalStorageDirectory().toString();// 得到根路径
File fileDir = new File(sdDir + "/SunLifeEverBright/Banca/Advertisement/");
if (!fileDir.exists()) {
fileDir.mkdirs();// 创建存放Banca广告的目录
}
String filepath = sdDir + "/SunLifeEverBright/Banca/Advertisement/" + fileMsg.getFileName();
File file = new File(filepath);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.flush();
fos.close();
AdvertItem item = new AdvertItem();
item.setFileName(e.getFileName());
item.setSort(Integer.valueOf(e.getShowNo()));
if (db != null) {
db.store(item);
db.commit();
}
}
if (index == fileMsgList.size() - 1)
Message.obtain(handler, REFRESHAD, 1, -1).sendToTarget();
}
} catch (DatabaseClosedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DatabaseReadOnlyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Db4oIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OptionalDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.vtion.sleb.banca.http;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.db4o.ObjectContainer;
import com.db4o.ext.DatabaseClosedException;
import com.db4o.ext.DatabaseReadOnlyException;
import com.db4o.ext.Db4oIOException;
import com.vtion.sleb.activities.R;
import com.vtion.sleb.banca.model.AdvertItem;
import com.vtion.sleb.banca.utils.SDUtils;
import com.vtion.sleb.entity.FileMsg;
public class FindAdByNameHttpClient extends Thread {
private static final int REFRESHAD = 0x124;
private Context context;
private Handler handler;
private List<FileMsg> fileMsgList;
private ObjectContainer db;
public FindAdByNameHttpClient(Context context, Handler handler, List<FileMsg> fileMsgList, ObjectContainer db) {
super();
this.context = context;
this.handler = handler;
this.fileMsgList = fileMsgList;
this.db = db;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
if (!SDUtils.checkSD())
return;
try {
int index = 0;
for (FileMsg e : fileMsgList) {
index = fileMsgList.indexOf(e);
String findAdByNameurl = context.getResources().getString(R.string.SERVER_URL) + "client/findAdByName.do?fileName=" + e.getFileId();
URL getUrl = new URL(findAdByNameurl);
HttpURLConnection connection = (HttpURLConnection) getUrl.openConnection();
connection.setRequestProperty("Accept-Charset", "utf-8");
connection.setRequestProperty("contentType", "utf-8");
connection.setRequestMethod("POST");
connection.setConnectTimeout(15 * 1000);
connection.setReadTimeout(15 * 1000);
connection.connect();
int responseCode = connection.getResponseCode();
// 服务器响应OK 状态吗=200
if (responseCode == 200) {
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream((connection.getInputStream())));
FileMsg fileMsg = (FileMsg) objectIn.readObject();
objectIn.close();
if (fileMsg == null)
return;
byte[] bytes = fileMsg.getImageFile(); // 得到图片的字节数据
String sdDir = Environment.getExternalStorageDirectory().toString();// 得到根路径
File fileDir = new File(sdDir + "/SunLifeEverBright/Banca/Advertisement/");
if (!fileDir.exists()) {
fileDir.mkdirs();// 创建存放Banca广告的目录
}
String filepath = sdDir + "/SunLifeEverBright/Banca/Advertisement/" + fileMsg.getFileName();
File file = new File(filepath);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.flush();
fos.close();
AdvertItem item = new AdvertItem();
item.setFileName(e.getFileName());
item.setSort(Integer.valueOf(e.getShowNo()));
if (db != null) {
db.store(item);
db.commit();
}
}
if (index == fileMsgList.size() - 1)
Message.obtain(handler, REFRESHAD, 1, -1).sendToTarget();
}
} catch (DatabaseClosedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DatabaseReadOnlyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Db4oIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OptionalDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
187

被折叠的 条评论
为什么被折叠?



