当前位置: 首页 > article >正文

蓝牙通信的简要设计与开发

文章目录

  • 简介
  • 前期工作
  • 一、核心代码
  • 二、实验结果
  • 源代码

简介

本次作业借助官方文档与其他文档实现简单的蓝牙通信。

前期工作

清单文件添加:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /><uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

一、核心代码

1.activity_main.xml 主页面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".BluetoothChat" ><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?attr/colorPrimary"android:minHeight="?attr/actionBarSize"android:theme="?attr/actionBarTheme" /><TextViewandroid:id="@+id/title_left_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="TextView" /><TextViewandroid:id="@+id/title_right_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="TextView" /><ListViewandroid:id="@+id/in"android:layout_width="match_parent"android:layout_height="562dp"android:transcriptMode="alwaysScroll" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"><EditTextandroid:id="@+id/edit_text_out"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:ems="10"android:inputType="textPersonName"android:text="Name" /><Buttonandroid:id="@+id/button_send"android:layout_width="wrap_content"android:layout_height="75dp"android:layout_weight="1"android:text="Button" /></LinearLayout></LinearLayout>

2.创建device_name.xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:id="@+id/title_paired_devices"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/title_paired_devices"android:visibility="gone"android:background="#666"android:textColor="#fff"android:paddingLeft="5dp" /><ListView android:id="@+id/paired_devices"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1" /><TextView android:id="@+id/title_new_devices"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/title_other_devices"android:visibility="gone"android:background="#666"android:textColor="#fff"android:paddingLeft="5dp" /><!--android:visibility="gone"表示不占空间的隐藏,invisible是占空间--><ListView android:id="@+id/new_devices"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="2" /><Button android:id="@+id/button_scan"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/button_scan" /></LinearLayout>

3.菜单界面创建

 <itemandroid:id="@+id/scan"android:icon="@android:drawable/ic_menu_myplaces"android:iconTint="#090909"android:title="@string/connect" /><itemandroid:id="@+id/discoverable"android:icon="@android:drawable/ic_menu_view"android:iconTint="#000000"android:title="@string/discoverable" /><itemandroid:id="@+id/back"android:icon="@android:drawable/ic_menu_close_clear_cancel"android:iconTint="#000000"android:title="@string/back" />

4.Chatservice类

public class ChatService {private static final String NAME = "BluetoothChat";//在创建蓝牙连接private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");private final BluetoothAdapter mAdapter;private final Handler mHandler;private AcceptThread mAcceptThread;private ConnectThread mConnectThread;private ConnectedThread mConnectedThread;private int mState;public static final int STATE_NONE = 0;public static final int STATE_LISTEN = 1;public static final int STATE_CONNECTING = 2;public static final int STATE_CONNECTED = 3;//构造方法,接收UI主线程传递的对象public ChatService(Context context, Handler handler) {//构造方法完成蓝牙对象的创建mAdapter = BluetoothAdapter.getDefaultAdapter();mState = STATE_NONE;mHandler = handler;}private synchronized void setState(int state) {mState = state;mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();}public synchronized int getState() {return mState;}public synchronized void start() {if (mConnectThread != null) {mConnectThread.cancel();mConnectThread = null;}if (mConnectedThread != null) {mConnectedThread.cancel();mConnectedThread = null;}if (mAcceptThread == null) {mAcceptThread = new AcceptThread();mAcceptThread.start();}setState(STATE_LISTEN);}//取消 CONNECTING 和 CONNECTED 状态下的相关线程,然后运行新的 mConnectThread 线程public synchronized void connect(BluetoothDevice device) {if (mState == STATE_CONNECTING) {if (mConnectThread != null) {mConnectThread.cancel();mConnectThread = null;}}if (mConnectedThread != null) {mConnectedThread.cancel();mConnectedThread = null;}mConnectThread = new ConnectThread(device);mConnectThread.start();setState(STATE_CONNECTING);}/*开启一个 ConnectedThread 来管理对应的当前连接。之前先取消任意现存的 mConnectThread 、mConnectedThread 、 mAcceptThread 线程,然后开启新 mConnectedThread ,传入当前刚刚接受的socket 连接。最后通过 Handler来通知UI连接*/public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {if (mConnectThread != null) {mConnectThread.cancel();mConnectThread = null;}if (mConnectedThread != null) {mConnectedThread.cancel();mConnectedThread = null;}if (mAcceptThread != null) {mAcceptThread.cancel();mAcceptThread = null;}mConnectedThread = new ConnectedThread(socket);mConnectedThread.start();Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);Bundle bundle = new Bundle();bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());msg.setData(bundle);mHandler.sendMessage(msg);setState(STATE_CONNECTED);}// 停止所有相关线程,设当前状态为 NONEpublic synchronized void stop() {if (mConnectThread != null) {mConnectThread.cancel();mConnectThread = null;}if (mConnectedThread != null) {mConnectedThread.cancel();mConnectedThread = null;}if (mAcceptThread != null) {mAcceptThread.cancel();mAcceptThread = null;}setState(STATE_NONE);}// 在 STATE_CONNECTED 状态下,调用 mConnectedThread 里的 write 方法,写入 bytepublic void write(byte[] out) {ConnectedThread r;synchronized (this) {if (mState != STATE_CONNECTED)return;r = mConnectedThread;}r.write(out);}// 连接失败的时候处理,通知 ui ,并设为 STATE_LISTEN 状态private void connectionFailed() {setState(STATE_LISTEN);Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);Bundle bundle = new Bundle();bundle.putString(BluetoothChat.TOAST, "链接不到设备");msg.setData(bundle);mHandler.sendMessage(msg);}// 当连接失去的时候,设为 STATE_LISTEN 状态并通知 uiprivate void connectionLost() {setState(STATE_LISTEN);Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);Bundle bundle = new Bundle();bundle.putString(BluetoothChat.TOAST, "设备链接中断");msg.setData(bundle);mHandler.sendMessage(msg);}// 创建监听线程,准备接受新连接。使用阻塞方式,调用 BluetoothServerSocket.accept()private class AcceptThread extends Thread {private final BluetoothServerSocket mmServerSocket;public AcceptThread() {BluetoothServerSocket tmp = null;try {//使用射频端口(RF comm)监听tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);} catch (IOException e) {}mmServerSocket = tmp;}@Overridepublic void run() {setName("AcceptThread");BluetoothSocket socket = null;while (mState != STATE_CONNECTED) {try {socket = mmServerSocket.accept();} catch (IOException e) {break;}if (socket != null) {synchronized (ChatService.this) {switch (mState) {case STATE_LISTEN:case STATE_CONNECTING:connected(socket, socket.getRemoteDevice());break;case STATE_NONE:case STATE_CONNECTED:try {socket.close();} catch (IOException e) {e.printStackTrace();}break;}}}}}public void cancel() {try {mmServerSocket.close();} catch (IOException e) {e.printStackTrace();}}}private class ConnectThread extends Thread {private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;public ConnectThread(BluetoothDevice device) {mmDevice = device;BluetoothSocket tmp = null;try {tmp = device.createRfcommSocketToServiceRecord(MY_UUID);} catch (IOException e) {e.printStackTrace();}mmSocket = tmp;}@Overridepublic void run() {setName("ConnectThread");mAdapter.cancelDiscovery();try {mmSocket.connect();} catch (IOException e) {connectionFailed();try {mmSocket.close();} catch (IOException e2) {e.printStackTrace();}ChatService.this.start();return;}synchronized (ChatService.this) {mConnectThread = null;}connected(mmSocket, mmDevice);}public void cancel() {try {mmSocket.close();} catch (IOException e) {e.printStackTrace();}}}private class ConnectedThread extends Thread {private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public ConnectedThread(BluetoothSocket socket) {mmSocket = socket;InputStream tmpIn = null;OutputStream tmpOut = null;try {tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch (IOException e) {e.printStackTrace();}mmInStream = tmpIn;mmOutStream = tmpOut;}@Overridepublic void run() {byte[] buffer = new byte[1024];int bytes;while (true) {try {bytes = mmInStream.read(buffer);mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer).sendToTarget();} catch (IOException e) {connectionLost();break;}}}public void write(byte[] buffer) {try {mmOutStream.write(buffer);mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();} catch (IOException e) {e.printStackTrace();}}public void cancel() {try {mmSocket.close();} catch (IOException e) {e.printStackTrace();}}}
}

5.DeviceList类创建

public class DeviceList extends AppCompatActivity {private BluetoothAdapter mBtAdapter;private ArrayAdapter<String> mPairedDevicesArrayAdapter;private ArrayAdapter<String> mNewDevicesArrayAdapter;public static String EXTRA_DEVICE_ADDRESS = "device_address";  //Mac地址//定义广播接收者,用于处理扫描蓝牙设备后的结果private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if (device.getBondState() != BluetoothDevice.BOND_BONDED) {mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());}} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {if (mNewDevicesArrayAdapter.getCount() == 0) {String noDevices = getResources().getText(R.string.none_found).toString();mNewDevicesArrayAdapter.add(noDevices);}}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.device_name);//在被调用活动里,设置返回结果码setResult(Activity.RESULT_CANCELED);init();  //活动界面}private void init() {Button scanButton = findViewById(R.id.button_scan);scanButton.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {Toast.makeText(DeviceList.this, R.string.scanning, Toast.LENGTH_LONG).show();doDiscovery();  //搜索蓝牙设备}});mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);//已配对蓝牙设备列表ListView pairedListView =findViewById(R.id.paired_devices);pairedListView.setAdapter(mPairedDevicesArrayAdapter);pairedListView.setOnItemClickListener(mPaireDeviceClickListener);//未配对蓝牙设备列表ListView newDevicesListView = findViewById(R.id.new_devices);newDevicesListView.setAdapter(mNewDevicesArrayAdapter);newDevicesListView.setOnItemClickListener(mNewDeviceClickListener);//动态注册广播接收者IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver, filter);filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);registerReceiver(mReceiver, filter);mBtAdapter = BluetoothAdapter.getDefaultAdapter();Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();if (pairedDevices.size() > 0) {findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);for (BluetoothDevice device : pairedDevices) {mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());}} else {String noDevices = getResources().getText(R.string.none_paired).toString();mPairedDevicesArrayAdapter.add(noDevices);}}@Overrideprotected void onDestroy() {super.onDestroy();if (mBtAdapter != null) {mBtAdapter.cancelDiscovery();}this.unregisterReceiver(mReceiver);}private void doDiscovery() {findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);if (mBtAdapter.isDiscovering()) {mBtAdapter.cancelDiscovery();}mBtAdapter.startDiscovery();  //开始搜索蓝牙设备并产生广播//找到一个设备时就发送一个BluetoothDevice.ACTION_FOUND的广播}private AdapterView.OnItemClickListener mPaireDeviceClickListener = new AdapterView.OnItemClickListener() {public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {mBtAdapter.cancelDiscovery();String info = ((TextView) v).getText().toString();String address = info.substring(info.length() - 17);Intent intent = new Intent();intent.putExtra(EXTRA_DEVICE_ADDRESS, address);  //Mac地址setResult(Activity.RESULT_OK, intent);finish();}};private AdapterView.OnItemClickListener mNewDeviceClickListener = new AdapterView.OnItemClickListener() {public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {mBtAdapter.cancelDiscovery();Toast.makeText(DeviceList.this, "请在蓝牙设置界面手动连接设备",Toast.LENGTH_SHORT).show();Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);startActivityForResult(intent,1);}};//回调方法:进入蓝牙配对设置界面返回后执行@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);init();  //刷新好友列表}
}

6.将MainActivity改名为BluetoothChat,代码如下:

public class BluetoothChat extends AppCompatActivity {public static final int MESSAGE_STATE_CHANGE = 1;public static final int MESSAGE_READ = 2;public static final int MESSAGE_WRITE = 3;public static final int MESSAGE_DEVICE_NAME = 4;public static final int MESSAGE_TOAST = 5;public static final String DEVICE_NAME = "device_name";public static final String TOAST = "toast";private static final int REQUEST_CONNECT_DEVICE = 1;  //请求连接设备private static final int REQUEST_ENABLE_BT = 2;private TextView mTitle;private ListView mConversationView;private EditText mOutEditText;private Button mSendButton;private String mConnectedDeviceName = null;private ArrayAdapter<String> mConversationArrayAdapter;private StringBuffer mOutStringBuffer;private BluetoothAdapter mBluetoothAdapter = null;private ChatService mChatService = null;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getSupportActionBar().hide();  //隐藏标题栏if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);}}Toolbar toolbar = findViewById(R.id.toolbar);//创建选项菜单toolbar.inflateMenu(R.menu.option_menu);//选项菜单监听toolbar.setOnMenuItemClickListener(new MyMenuItemClickListener());mTitle = findViewById(R.id.title_left_text);mTitle.setText(R.string.app_name);mTitle = findViewById(R.id.title_right_text);// 得到本地蓝牙适配器mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if (mBluetoothAdapter == null) {Toast.makeText(this, "蓝牙不可用", Toast.LENGTH_LONG).show();finish();return;}if (!mBluetoothAdapter.isEnabled()) { //若当前设备蓝牙功能未开启Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableIntent, REQUEST_ENABLE_BT); //} else {if (mChatService == null) {setupChat();  //创建会话}}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if(grantResults.length>0){if(grantResults[0]!=PackageManager.PERMISSION_GRANTED){Toast.makeText(this, "未授权,蓝牙搜索功能将不可用!", Toast.LENGTH_SHORT).show();}}}@Overridepublic synchronized void onResume() {  //synchronized:同步方法实现排队调用super.onResume();if (mChatService != null) {if (mChatService.getState() == ChatService.STATE_NONE) {mChatService.start();}}}private void setupChat() {mConversationArrayAdapter = new ArrayAdapter<String>(this,R.layout.activity_main);mConversationView = findViewById(R.id.in);mConversationView.setAdapter(mConversationArrayAdapter);mOutEditText = findViewById(R.id.edit_text_out);mOutEditText.setOnEditorActionListener(mWriteListener);mSendButton = findViewById(R.id.button_send);mSendButton.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {TextView view = findViewById(R.id.edit_text_out);String message = view.getText().toString();sendMessage(message);}});//创建服务对象mChatService = new ChatService(this, mHandler);mOutStringBuffer = new StringBuffer("");}@Overridepublic void onDestroy() {super.onDestroy();if (mChatService != null)mChatService.stop();}private void ensureDiscoverable() { //修改本机蓝牙设备的可见性//打开手机蓝牙后,能被其它蓝牙设备扫描到的时间不是永久的if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//设置在300秒内可见(能被扫描)discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);startActivity(discoverableIntent);Toast.makeText(this, "已经设置本机蓝牙设备的可见性,对方可搜索了。", Toast.LENGTH_SHORT).show();}}private void sendMessage(String message) {if (mChatService.getState() != ChatService.STATE_CONNECTED) {Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();return;}if (message.length() > 0) {byte[] send = message.getBytes();mChatService.write(send);mOutStringBuffer.setLength(0);mOutEditText.setText(mOutStringBuffer);}}private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {@Overridepublic boolean onEditorAction(TextView view, int actionId, KeyEvent event) {if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {//软键盘里的回车也能发送消息String message = view.getText().toString();sendMessage(message);}return true;}};//使用Handler对象在UI主线程与子线程之间传递消息private final Handler mHandler = new Handler() {   //消息处理@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MESSAGE_STATE_CHANGE:switch (msg.arg1) {case ChatService.STATE_CONNECTED:mTitle.setText(R.string.title_connected_to);mTitle.append(mConnectedDeviceName);mConversationArrayAdapter.clear();break;case ChatService.STATE_CONNECTING:mTitle.setText(R.string.title_connecting);break;case ChatService.STATE_LISTEN:case ChatService.STATE_NONE:mTitle.setText(R.string.title_not_connected);break;}break;case MESSAGE_WRITE:byte[] writeBuf = (byte[]) msg.obj;String writeMessage = new String(writeBuf);mConversationArrayAdapter.add("我:  " + writeMessage);break;case MESSAGE_READ:byte[] readBuf = (byte[]) msg.obj;String readMessage = new String(readBuf, 0, msg.arg1);mConversationArrayAdapter.add(mConnectedDeviceName + ":  "+ readMessage);break;case MESSAGE_DEVICE_NAME:mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);Toast.makeText(getApplicationContext(),"链接到 " + mConnectedDeviceName, Toast.LENGTH_SHORT).show();break;case MESSAGE_TOAST:Toast.makeText(getApplicationContext(),msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();break;}}};//返回进入好友列表操作后的数回调方法public void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case REQUEST_CONNECT_DEVICE:if (resultCode == Activity.RESULT_OK) {String address = data.getExtras().getString(DeviceList.EXTRA_DEVICE_ADDRESS);BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);mChatService.connect(device);} else if (resultCode == Activity.RESULT_CANCELED) {Toast.makeText(this, "未选择任何好友!", Toast.LENGTH_SHORT).show();}break;case REQUEST_ENABLE_BT:if (resultCode == Activity.RESULT_OK) {setupChat();} else {Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();finish();}}}//内部类,选项菜单的单击事件处理private class MyMenuItemClickListener implements Toolbar.OnMenuItemClickListener {@Overridepublic boolean onMenuItemClick(MenuItem item) {switch (item.getItemId()) {case R.id.scan://启动DeviceList这个ActivityIntent serverIntent = new Intent(BluetoothChat.this, DeviceList.class);startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);return true;case R.id.discoverable:ensureDiscoverable();return true;case R.id.back:finish();System.exit(0);return true;}return false;}}
}

二、实验结果

在这里插入图片描述

源代码

代码仓库

http://www.lryc.cn/news/2417960.html

相关文章:

  • vs 2010 express 序列号
  • flash 小游戏大全
  • Java对接微信扫码支付Native支付-V3版本接口
  • 卡巴斯基安全浏览器_向苹果开炮:卡巴斯基向监管部门投诉苹果垄断
  • 牛根生北大演讲
  • AutoCAD各版本对应的R版本参数值及其对应注册表中的数值(2002-2023)
  • 万网m3 windows linux切换,万网M3-linux虚拟主机开启网页Gzip压缩方法
  • ElasticSearch的常用命令操作
  • 获取windows版本号
  • 2021国赛数据处理
  • 《〈XNova/OGame〉源码笔记》(5)
  • 精通api接口测试,接口分类,接口架构,http,webservice,dubbo接口协议,接口流程,接口工具,cookie,session,token接口鉴权原理以及实战
  • BT5156 - http://bbs.bt5156.com
  • 农业网址导航
  • 黑莓开源产品
  • 1+X云计算
  • socket中的select函数使用
  • jQuery动画效果(show与hide/toggle/slideUp/slideToggle/fadeIn/fadeTo)
  • VC常用几种界面库的选择
  • 五、asp常用对象
  • Gridview中几个Button的应用
  • 日志分析与安全
  • Everyme:类似QQ圈子的社交应用
  • 12款个人防火墙软件横向评测
  • 基于51单片机的GPS定位系统设计
  • 七夕表白爱心代码,可任意自定义名字
  • 短地址
  • Ophone2.0开发环境的搭建
  • python-类的属性和方法练习
  • MyEclipse7.5+EclipseMe+WTK2.5搭建J2ME开发环境