我正在尝试使用 WiFip2p 创建一个聊天应用程序。一切都在这个应用程序中完成。在发送和接收消息之前,应用程序运行良好。之后,我得到了这个错误。当我连接到另一台设备时出现此错误。它显示一个空对象引用。我不知道为什么我需要一个解决方案,任何人都可以帮助我,谢谢。
public class WiFi_Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wi_fi_);
FINDVIEWBYID();
CLICKLISTINER();
}
Handler handler=new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what)
{
case MESSAGE_READ:
byte[] readbuffer=(byte[])msg.obj;
String tempmez=new String(readbuffer,0,msg.arg1);
txt_message.setText(tempmez);
break;
}
return true;
}
});
private void FINDVIEWBYID() {
btn_onoff=findViewById(R.id.onOff);
btn_discover=findViewById(R.id.discover);
btn_send=findViewById(R.id.sendButton);
listView=findViewById(R.id.peerListView);
txt_connectionsts=findViewById(R.id.connectionStatus);
txt_message=findViewById(R.id.readMsg);
edit_message=findViewById(R.id.writeMsg);
wifiManager= (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiP2pManager= (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel=wifiP2pManager.initialize(this,getMainLooper(),null);
broadcastReceiver=new Wifi_broadcast_reciever(wifiP2pManager,channel,this);
intentFilter=new IntentFilter();
intentFilter.addAction(wifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(wifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(wifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(wifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
private void CLICKLISTINER() {
btn_onoff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (wifiManager.isWifiEnabled())
{
wifiManager.setWifiEnabled(false);
btn_onoff.setText("ON");
}
else
{
wifiManager.setWifiEnabled(true);
btn_onoff.setText("OFF");
}
}
});
btn_discover.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
txt_connectionsts.setText("Discovery Started");
}
@Override
public void onFailure(int reason) {
txt_connectionsts.setText("Discovery starting failuree"+String.valueOf(reason));
}
});
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final WifiP2pDevice wifiP2pDevice=devicearray[position];
WifiP2pConfig config=new WifiP2pConfig();
config.deviceAddress=wifiP2pDevice.deviceAddress;
wifiP2pManager.connect(channel, config, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(WiFi_Activity.this, "Connect with"+ wifiP2pDevice.deviceName, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reason) {
Toast.makeText(WiFi_Activity.this, "Not connected", Toast.LENGTH_SHORT).show();
}
});
}
});
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msz=edit_message.getText().toString();
sendRecieve.write(msz.getBytes());
}
});
}
WifiP2pManager.PeerListListener peerListListener=new WifiP2pManager.PeerListListener() {
@Override
public void onPeersAvailable(WifiP2pDeviceList peerslist) {
if (!peerslist.getDeviceList().equals(peers));
{
peers.clear();
peers.addAll(peerslist.getDeviceList());
devicename_array=new String[peerslist.getDeviceList().size()];
devicearray=new WifiP2pDevice[peerslist.getDeviceList().size()];
int index= 0;
for (WifiP2pDevice device:peerslist.getDeviceList())
{
devicename_array[index]=device.deviceName;
devicearray[index]=device;
index++;
}
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(getApplicationContext(),R.layout.support_simple_spinner_dropdown_item,devicename_array);
listView.setAdapter(arrayAdapter);
}
if (peers.size()==0)
{
Toast.makeText(WiFi_Activity.this, "No discover show", Toast.LENGTH_SHORT).show();
}
}
};
WifiP2pManager.ConnectionInfoListener connectionInfoListener=new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
final InetAddress owneraddress= info.groupOwnerAddress;
if (info.groupFormed && info.isGroupOwner)
{
txt_connectionsts.setText("Host");
serverclass=new Serverclass();
serverclass.start();
}
else if (info.groupFormed)
{
txt_connectionsts.setText("Client");
clientclass = new Clientclass(owneraddress);
clientclass.start();
}
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(broadcastReceiver,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
public class Serverclass extends Thread
{
Socket socket;
ServerSocket serverSocket;
@Override
public void run() {
try {
serverSocket=new ServerSocket(1111);
socket=serverSocket.accept();
sendRecieve=new SendRecieve(socket);
sendRecieve.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Clientclass extends Thread
{
Socket socket;
String host_address;
public Clientclass(InetAddress hostaddress){
host_address=hostaddress.getHostAddress();
socket=new Socket();
sendRecieve=new SendRecieve(socket);
sendRecieve.start();
}
@Override
public void run() {
try {
socket.connect(new InetSocketAddress(host_address,1111),500);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class SendRecieve extends Thread
{
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendRecieve(Socket skt)
{
socket=skt;
try {
inputStream=socket.getInputStream();
outputStream=socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
byte[] buffer=new byte[2048];
int bytes;
while (socket!=null)
{
try {
bytes=inputStream.read(buffer);
if (bytes>0)
{
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
Log.d("error",e.getMessage());
}
}
}
public void write(byte[] bytes)
{
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我在这部分代码中遇到此错误:-
@Override
public void run() {
byte[] buffer=new byte[2048];
int bytes;
while (socket!=null)
{
try {
bytes=inputStream.read(buffer);
if (bytes>0)
{
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
Log.d("error",e.getMessage());
}
}
}
我认为唯一的问题是您捕获(并忽略)来自
getInputStream()
和 getOutputStream()
的错误。例外情况是停止执行,因此如果 getInputStream()
出错,则不会设置。您的两个流都将为空。
由于您至少要打印堆栈跟踪,因此请在实际崩溃之前检查其他堆栈跟踪。它可能会告诉您更多有关问题所在的信息。
为了解决这个问题,我建议不要捕获异常,而是让构造函数抛出
IOException
。如果你早点发现,以后给你带来的问题就会减少。
编辑:我又仔细看了你的课程,发现你没有及时设置
Socket
的地址。在获取数据流之前执行此操作。不使用这些字段也可以。
private Socket socket;
public SendRecieve(Socket skt) {
this.socket = skt;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
... etc
} ...
}
您在 Clientclas run 执行之前调用 Sendreceiver start,因此以下操作是必要的:
public class Clientclass extends Thread {
Socket socket;
String host_address;
public Clientclass(InetAddress hostaddress){
host_address=hostaddress.getHostAddress();
socket=new Socket();
}
@Override
public void run() {
try {
socket.connect(new InetSocketAddress(host_address,1111),500);
sendRecieve=new SendRecieve(socket);
sendRecieve.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
就我而言,即使这是一个蓝牙问题,我认为这也可能适用于 Wifi 和其他套接字连接,经过几天的调试,问题在于 Android Studio 不会编译以下代码:我的应用程序WITHOUT我的程序在几乎每次调用与套接字连接相关的任何内容之前都会执行(蓝牙)权限检查(
checkSelfPermission
),包括mBTSocket.connect()
。我的代码在 Android >= 12 上完美运行,但在 Android 7 和 9 上崩溃(我用来测试它的设备以及运行实际应用程序的主要设备)。由于我必须在代码中进行多次检查,因此我编写了一个可以进行检查的方法,并且 Android Studio 接受了该方法。然而,在错误地检查我们正在运行的平台的 SDK 版本后,该方法将返回 false
,这意味着 mBTSocket.connect()
方法从未被调用,因此套接字对象的 InputStream
和 OutputStream
unset/null,这会导致此异常。希望这可以节省一些人的时间。