
一个客户端要发起一次通信,首先必须知道运行服务器端的主机IP地址。然后由网络基础设施利用目标地址,将客户端发送的信息传递到正确的主机上,在Java中,地址可以由一个字符串来定义,这个字符串可以使数字型的地址(比如192.168.1.1),也可以是主机名(example.com)。
而在android 4.0 之后系统以后就禁止在主线程中进行网络访问了,原因是:
主线程是负责UI的响应,如果在主线程进行网络访问,超过5秒的话就会引发强制关闭,所以这种耗时的 *** 作不能放在主线程里。放在子线程里,而子线程里是不能对主线程的UI进行改变的,因此就引出了Handler,主线程里定义Handler,子线程里使用。
以下是一个android socket客户端的例子:
---------------------------------Java代码---------------------------------------
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.PrintStream
import java.io.UnsupportedEncodingException
import java.net.InetSocketAddress
import java.net.Socket
import java.net.UnknownHostException
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
public class TCPSocketActivity extends Activity {
public static final String TAG = TCPSocketActivity.class.getSimpleName()
/* 服务器地址 */
private String host_ip = null
/* 服务器端口 */
private int host_port = 0
private Button btnConnect
private Button btnSend
private EditText editSend
private EditText hostIP
private EditText hostPort
private Socket socket
private PrintStream output
private String buffer = ""
private Context context
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_socket_test)
context = this
initView()
btnConnect.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
host_ip = hostIP.getText().toString()
host_port = Integer.parseInt(hostPort.getText().toString())
new Thread(new ConnectThread()).start()
}
})
btnSend.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new SendThread(editSend.getText().toString())).start()
}
})
}
private void toastText(String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
public void handleException(Exception e, String prefix) {
e.printStackTrace()
toastText(prefix + e.toString())
}
public void initView() {
btnConnect = (Button) findViewById(R.id.btnConnect)
btnSend = (Button) findViewById(R.id.btnSend)
editSend = (EditText) findViewById(R.id.sendMsg)
hostIP = (EditText) findViewById(R.id.hostIP)
hostPort = (EditText) findViewById(R.id.hostPort)
}
private void closeSocket() {
try {
output.close()
socket.close()
} catch (IOException e) {
handleException(e, "close exception: ")
}
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg)
if (0x123 == msg.what) {
toastText("连接成功!")
}
}
}
/* 连接socket线程 */
public class ConnectThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
Message msg = Message.obtain()
try {
if (null == socket || socket.isClosed()) {
socket = new Socket()
socket.connect(new InetSocketAddress(host_ip,host_port),5000)
output = new PrintStream(socket.getOutputStream(), true,
"utf-8")
}
msg.what = 0x123
handler.sendMessage(msg)
} catch (UnsupportedEncodingException e) {
e.printStackTrace()
} catch (IOException e) {
e.printStackTrace()
}
}
}
/*发送信息线程*/
public class SendThread implements Runnable {
String msg
public SendThread(String msg) {
super()
this.msg = msg
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
output.print(msg)
} catch (Exception e) {
e.printStackTrace()
}
closeSocket()
}
}
public class SocketThread implements Runnable {
public String txt1
public SocketThread(String txt1) {
super()
this.txt1 = txt1
}
@Override
public void run() {
// TODO Auto-generated method stub
Message msg = Message.obtain()
try {
/* 连接服务器 并设置连接超时为5秒 */
if (socket.isClosed() || null == socket) {
socket = new Socket()
socket.connect(new InetSocketAddress(host_ip,host_port),5000)
}
// 获取输入输出流
PrintStream ou = new PrintStream(socket.getOutputStream(),
true, "UTF-8")
BufferedReader bff = new BufferedReader(new InputStreamReader(
socket.getInputStream()))
// 读取发来服务器信息
String line = null
buffer = ""
while ((line = bff.readLine()) != null) {
buffer = line + buffer
}
// 向服务器发送信息
ou.print(txt1)
ou.flush()
// 关闭各种输入输出流
bff.close()
ou.close()
socket.close()
msg.what = 0x123
handler.sendMessage(msg)
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
}
-----------------------------布局文件activity_socket_test.xml--------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/white"
android:orientation="vertical" >
<EditText
android:id="@+id/hostIP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="服务器ip"
android:singleLine="true"
android:inputType="text" />
<EditText
android:id="@+id/hostPort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="端口"
android:singleLine="true"
android:inputType="number" />
<Button
android:id="@+id/btnConnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:background="@drawable/style_btn_shape"
android:layout_margin="5dip"
android:text="@string/connect"
android:textColor="@color/white" />
<EditText
android:id="@+id/sendMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:hint="需要发送的内容"
android:inputType="text" />
<Button
android:id="@+id/btnSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:background="@drawable/style_btn_shape"
android:layout_gravity="center_vertical|center_horizontal"
android:text="@string/send"
android:textColor="@color/white" />
</LinearLayout>
-------------------------样式文件style_btn_shape.xml----------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#0465b2" />
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="15dip" />
<!-- padding:Button里面的文字与Button边界的间隔 -->
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp"
/>
</shape>
------------------------------END---------------------------------------
常量类:ConstantUtil
public class ConstantUtil {// 数据库名称
public static final String DATABASE_NAME = "user_manager.db"
// 数据库版本号
public static final int DATABASE_VERSION = 1
//表名
public static final String TABLE_NAME = "user_info"
//字段名
public static final String USER_ID = "userId"
public static final String USER_NAME = "username"
public static final String USER_PASSWORD = "password"
public static final String USER_ADDRESS = "address"
}
自定义SQLiteOpenHelper:MySQLiteOpenHelper
public class MySQLiteOpenHelper extends SQLiteOpenHelper {// 定义一个SQLiteDatabase对象,对表进行相应的 *** 作
private SQLiteDatabase mDatabase
public MySQLiteOpenHelper(Context context) {
super(context, ConstantUtil.DATABASE_NAME, null,
ConstantUtil.DATABASE_VERSION)
mDatabase = getWritableDatabase()
}
/*
* 创建表
*/
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
//sql语句
String sql = "create table " + ConstantUtil.TABLE_NAME + "("
+ ConstantUtil.USER_ID + " integer primary key,"
+ ConstantUtil.USER_NAME + " text not null,"
+ ConstantUtil.USER_PASSWORD + " text not null,"
+ ConstantUtil.USER_ADDRESS + " text not null)"
db.execSQL(sql)
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
onCreate(db)
}
/**
* 添加数据
* @param cv
* @return
*/
public boolean insertData(ContentValues cv){
return mDatabase.insert(ConstantUtil.TABLE_NAME, null, cv)>0
}
/**
* 查询所有数据
* @return
*/
public List<Userinfo> queryData(){
List<Userinfo> userinfos=new ArrayList<Userinfo>()
//从数据库里查询数据
Cursor cursor=mDatabase.query(ConstantUtil.TABLE_NAME, null, null, null, null, null, null)
if(cursor!=null){
//取出数据
while (cursor.moveToNext()) {
Userinfo userinfo=new Userinfo()
userinfo.setUserId(cursor.getInt(0))
userinfo.setUsername(cursor.getString(1))
userinfo.setPassword(cursor.getString(2))
userinfo.setAddress(cursor.getString(3))
userinfos.add(userinfo)
}
}
return userinfos
}
}
主Activity
public class MainActivity extends Activity {// 控件
private TextView txtName, txtPwd, txtAddress
private EditText edtName, edtPwd, edtAddress
private ListView mListView
// 数据库对象
private MySQLiteOpenHelper mySQLiteOpenHelper
private UserinfoAdapter adapter
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
findView()
init()
}
private void findView() {
// TODO Auto-generated method stub
edtName = (EditText) findViewById(R.id.id_edit1)
edtPwd = (EditText) findViewById(R.id.id_edit2)
edtAddress = (EditText) findViewById(R.id.id_edit3)
mListView = (ListView) findViewById(R.id.id_listview)
}
private void init() {
// TODO Auto-generated method stub
mySQLiteOpenHelper = new MySQLiteOpenHelper(MainActivity.this)
}
public void onAction(View v) {
switch (v.getId()) {
case R.id.id_btn_add:
//添加数据
String userName=edtName.getText().toString()
String userPwd=edtPwd.getText().toString()
String userAdress=edtAddress.getText().toString()
//传入参数
ContentValues cv=new ContentValues()
//列名和值
cv.put(ConstantUtil.USER_NAME, userName)
cv.put(ConstantUtil.USER_PASSWORD, userPwd)
cv.put(ConstantUtil.USER_ADDRESS, userAdress)
//得到结果
boolean flag=mySQLiteOpenHelper.insertData(cv)
if (flag) {
Toast.makeText(MainActivity.this, "添加记录成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(MainActivity.this, "添加记录失败", Toast.LENGTH_SHORT).show()
}
break
case R.id.id_btn_query:
//查询数据
List<Userinfo> userinfos=mySQLiteOpenHelper.queryData()
if (adapter!=null) {
adapter=null
}
adapter=new UserinfoAdapter(userinfos)
mListView.setAdapter(adapter)
break
default:
break
}
}
//数据适配器
class UserinfoAdapter extends BaseAdapter{
List<Userinfo> userinfos
public UserinfoAdapter(List<Userinfo> _userinfos){
this.userinfos=_userinfos
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return userinfos.size()
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return userinfos.get(position)
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
convertView=LayoutInflater.from(MainActivity.this).inflate(R.layout.listview_item, null)
txtName=(TextView) convertView.findViewById(R.id.id_txt_name)
txtPwd=(TextView) convertView.findViewById(R.id.id_txt_pwd)
txtAddress=(TextView) convertView.findViewById(R.id.id_txt_address)
txtName.setText(userinfos.get(position).getUsername())
txtPwd.setText(userinfos.get(position).getPassword())
txtAddress.setText(userinfos.get(position).getAddress())
}
return convertView
}
}
}
完整源码下载地址(附数据库文件查询软件+运行效果图):
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)