写了一个应用mainactivity启动服务,在service中启动socket服务,socket捕获异常在service中弹出dialog,但就是不行。
每次都弹出这个错误,但改主题也没用还是弹出这个错误,哪位给看一下
FATAL EXCEPTION: Thread-4
Process: com.example.msslapp, PID: 22716
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
android 使用 service弹出dialog
mainactivity是
public class MainActivity extends AppCompatActivity {
private final int SERVER_PORT = 26666;//端口号
private final String SERVER_IP = "192.168.1.101";//连接IP
TcpConnectThread tcpthread;
TextView tv1;
EditText et1,et2,et3,et4;
Button btn1,btn2,btn3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 =(TextView) findViewById(R.id.tv1);
et1 =(EditText) findViewById(R.id.et1);
btn1=(Button) findViewById(R.id.btn1);
et2 =(EditText) findViewById(R.id.et2);
et3 =(EditText) findViewById(R.id.et3);
et4 =(EditText) findViewById(R.id.et4);
btn2=(Button) findViewById(R.id.btn2);
btn3=(Button) findViewById(R.id.btn3);
Intent regIntent = new Intent(this, SocketService.class);
regIntent.putExtra("IP", SERVER_IP);
regIntent.putExtra("PORT",SERVER_PORT);
startService(regIntent);
// tcpthread = new TcpConnectThread(SERVER_IP,SERVER_PORT,getApplicationContext());
// tcpthread.start();
//发送消息模式为test的消息
btn1.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
String str=et1.getText().toString();
TCPsend ts=new TCPsend(tcpthread.Client_ssl,"test",str);
new Thread(ts).start();
}
});
//发送消息模式为key的消息
btn2.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
String key= et2.getText().toString();
String data= et3.getText().toString();
String context =et4.getText().toString();
TCPsend ts=new TCPsend(SocketService.Client_ssl,key,data,context);
new Thread(ts).start();
}
});
btn3.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
EventBus.getDefault().post(new MyEvent("123456"));
}
});
/*
if(EventBus.getDefault().isRegistered(this)){
System.out.println("已经注册");
}
else if(!EventBus.getDefault().isRegistered(this)){
System.out.println("注册失败");
}*/
EventBus.getDefault().register(this);
}
@Override
public void onDestroy() {
// TCPsend ts=new TCPsend(tcpthread.Client_ssl,"type","Quit");
// new Thread(ts).start();
super.onDestroy();
MainActivity.this.stopService(new
Intent(MainActivity.this,
SocketService.class));
EventBus.getDefault().unregister(this); //取消注册
}
//接收eventbus消息
@Subscribe(threadMode = ThreadMode.MAIN)
public void EventbusMain(MyEvent te) {
tv1.setText(te.getdata());
}
}
service为
public class SocketService extends Service {
private static final String CLIENT_KET_PASSWORD = "changeit";//私钥密码
private static final String CLIENT_TRUST_PASSWORD = "changeit";//信任证书密码
private static final String CLIENT_AGREEMENT = "SSL";//使用协议
private static final String CLIENT_KEY_MANAGER = "X509";//密钥管理器
private static final String CLIENT_TRUST_MANAGER = "X509";//
private static final String CLIENT_KEY_KEYSTORE = "BKS";//密库,这里用的是BouncyCastle密库
private static final String CLIENT_TRUST_KEYSTORE = "BKS";//
/*连接线程*/
private Thread connectThread;
private Timer timer = new Timer();
//private OutputStream outputStream;
private SocketBinder sockerBinder = new SocketBinder();
private String ip;
private int port;
private TimerTask task;
static SSLSocket Client_ssl;
/*默认重连*/
private boolean isReConnect = true;
private Handler handler;
@Override
public IBinder onBind(Intent intent) {
return sockerBinder;
}
public class SocketBinder extends Binder {
/*返回SocketService 在需要的地方可以通过ServiceConnection获取到SocketService */
public SocketService getService() {
return SocketService.this;
}
}
@Override
public void onCreate() {
handler = new Handler(Looper.getMainLooper());
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/*拿到传递过来的ip和端口号*/
ip = intent.getStringExtra("IP");
port =intent.getIntExtra("PORT",0) ;
/*初始化socket*/
initSocket();
return super.onStartCommand(intent, flags, startId);
}
/*初始化socket*/
private void initSocket() {
if (Client_ssl == null && connectThread == null) {
connectThread = new Thread(new Runnable() {
@Override
public void run() {
try {
final SSLContext sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
//取得KeyManagerFactory和TrustManagerFactory的X509密钥管理器实例
KeyManagerFactory keyManager = KeyManagerFactory.getInstance(CLIENT_KEY_MANAGER);
TrustManagerFactory trustManager = TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);
//取得BKS密库实例
KeyStore kks = KeyStore.getInstance(CLIENT_KEY_KEYSTORE);
KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
//加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
kks.load(getBaseContext().getAssets().open("client.bks"), CLIENT_KET_PASSWORD.toCharArray());
tks.load(getBaseContext().getAssets().open("client.bks"), CLIENT_TRUST_PASSWORD.toCharArray());
//初始化密钥管理器
keyManager.init(kks, CLIENT_KET_PASSWORD.toCharArray());
trustManager.init(tks);
//初始化SSLContext
sslContext.init(keyManager.getKeyManagers(), trustManager.getTrustManagers(), null);
Client_ssl = (SSLSocket) sslContext.getSocketFactory().createSocket(ip, port);
System.out.println("正在连接");
/*连接成功的话 发送心跳包*/
if (Client_ssl.isConnected()) {
/*因为Toast是要运行在主线程的 这里是子线程 所以需要到主线程哪里去显示toast*/
toastMsg("socket已连接");
TcpConnectThread tcpthread = new TcpConnectThread(Client_ssl,getApplicationContext());
tcpthread.start();
/*发送心跳数据*/
sendBeatData();
}
} catch (IOException e) {
e.printStackTrace();
if (e instanceof SocketTimeoutException) {
toastMsg("连接超时");
releaseSocket();
} else if (e instanceof NoRouteToHostException) {
toastMsg("该地址不存在,请检查");
stopSelf();
} else if (e instanceof ConnectException) {
toastMsg("连接异常或被拒绝,请检查");
releaseSocket();
//stopSelf();
}
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
});
/*启动连接线程*/
connectThread.start();
}
}
/*定时发送数据*/
private void sendBeatData() {
if (timer == null) {
timer = new Timer();
}
if (task == null) {
task = new TimerTask() {
@Override
public void run() {
try {
Message msg=new Message();
msg.putmsgmap("type","Beat");
MyObjectOutputStream moos;
moos =new MyObjectOutputStream(Client_ssl.getOutputStream());
moos.writeObject(msg);
moos.flush();
} catch (Exception e) {
/*发送失败说明socket断开了或者出现了其他错误*/
//toastMsg("连接断开,正在重连");
/*重连*/
releaseSocket();
e.printStackTrace();
}
}
};
}
timer.schedule(task, 0, 2000);
}
/*释放资源*/
private void releaseSocket() {
if (task != null) {
task.cancel();
task = null;
}
if (timer != null) {
timer.purge();
timer.cancel();
timer = null;
}
if (Client_ssl != null) {
try {
Client_ssl.close();
} catch (IOException e) {
}
Client_ssl = null;
}
if (connectThread != null) {
connectThread = null;
}
/*重新初始化socket*/
if (isReConnect) {
showDialog();
//initSocket();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("SocketService", "onDestroy");
isReConnect = false;
releaseSocket();
}
/*因为Toast是要运行在主线程的 所以需要到主线程哪里去显示toast*/
private void toastMsg(final String msg) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("连接已经断开,是否重新连接");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
initSocket();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
isReConnect = false;
}
});
AlertDialog alertDialog = builder.create();
//alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
alertDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY));
}else {
alertDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
}
alertDialog.setCanceledOnTouchOutside(true);
alertDialog.show();
new Thread(){
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
alertDialog.show();
}
});
};
}.start();
}
}
在服务中调用方法
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("连接已经断开,是否重新连接");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
initSocket();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
isReConnect = false;
}
});
AlertDialog alertDialog = builder.create();
//alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
alertDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY));
}else {
alertDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
}
alertDialog.setCanceledOnTouchOutside(true);
alertDialog.show();
new Thread(){
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
alertDialog.show();
}
});
};
}.start();
}
权限也加了
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET"/>