android做客户端socket如何让点击按钮向服务器发送信息

android做客户端socket如何让点击按钮向服务器发送信息,第1张

使用基于TCP协议的Socket

一个客户端要发起一次通信,首先必须知道运行服务器端的主机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

}

}

}

完整源码下载地址(附数据库文件查询软件+运行效果图):


欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/sjk/9391966.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存