我希望我的Android应用程序在互联网连接丢失时显示一个弹出窗口,以告诉用户他丢失了连接,我试图捕获空流然后启动弹出窗口,但它给出了我那个例外:
03-20 10:16:35.015:W / System.err(2922): android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌null无效;你的活动在运行吗? 03-20 10:16:35.016:W / System.err(2922):在android.view.ViewRootImpl.setView(ViewRootImpl.java:646) 03-20 10:16:35.016:W / System.err(2922):在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248) 03-20 10:16:35.016:W / System.err(2922):在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 03-20 10:16:35.016:W / System.err(2922):在android.widget.PopupWindow.invokePopup(PopupWindow.java:993) 03-20 10:16:35.016:W / System.err(2922):在android.widget.PopupWindow.showAtLocation(PopupWindow.java:847) 03-20 10:16:35.016:W / System.err(2922):在android.widget.PopupWindow.showAtLocation(PopupWindow.java:811) 03-20 10:16:35.016:W / System.err(2922):at com.example.solaceap.Login $ 5.run(Login.java:135) 03-20 10:16:35.016:W / System.err(2922):在android.app.Activity.runOnUiThread(Activity.java:4662) 03-20 10:16:35.016:W / System.err(2922):at com.example.solaceap.Login.init_conn_lost_popup(Login.java:119) 03-20 10:16:35.016:W / System.err(2922):at com.example.solaceap.Login $ 6 $ 1.run(Login.java:281) 03-20 10:16:35.016:W / System.err(2922):在android.os.Handler.handleCallback(Handler.java:725) 03-20 10:16:35.017:W / System.err(2922):在android.os.Handler.dispatchMessage(Handler.java:92) 03-20 10:16:35.017:W / System.err(2922):在android.os.Looper.loop(Looper.java:153) 03-20 10:16:35.017:W / System.err(2922):在android.app.ActivityThread.main(ActivityThread.java:5299) 03-20 10:16:35.017:W / System.err(2922):at java.lang.reflect.Method.invokeNative(Native Method) 03-20 10:16:35.017:W / System.err(2922):at java.lang.reflect.Method.invoke(Method.java:511) 03-20 10:16:35.017:W / System.err(2922):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:833) 03-20 10:16:35.017:W / System.err(2922):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 03-20 10:16:35.017:W / System.err(2922):at dalvik.system.NativeStart.main(Native Method)
我不知道应用程序在运行之前是否已崩溃,或者因为我当时没有处于膨胀的活动中,而且这是我的代码:
值得一提的是,流是从一个普通的java类中获取的,它实现了Runnable
而不是一个活动类,因为我只是运行了一个不断给我输入数据来自流的线程,看看:
public String getServerResponse() throws JSONException {
String responseLine, server_response = null_string;
InputStream stream = null;
try{
stream = socket.getInputStream();
}catch(Exception e){
e.printStackTrace();
Login login = new Login();
login.init_conn_lost_popup();
}
if(stream != null){
input = new BufferedReader(new InputStreamReader(
stream));
try {
while ((responseLine = input.readLine()) != null){
server_response = server_response + responseLine;
}
} catch (IOException e) {
Login.errorMessage.setText(conn_err);
}
}
return null;
}
然后在第一个运行过去线程的活动中:
Thread run_time = new Thread() {
@Override
public void run() {
ConnectToServer connect = new ConnectToServer(); // this is the Runnable class
while (true) {
String server_response = null;
try {
server_response = connect.getServerRespons(Login.this);
} catch (Exception e1) {
}
try {
if (!server_response.equals(null)) {
}
} catch (Exception e) {
if (!this.isInterrupted()) {
flag = true;
runOnUiThread(new Runnable() {
public void run() {
flag = false;
init_conn_lost_popup();
}
});
}
}
}
}
};
run_time.start();
这是pop_up方法:
public void init_conn_lost_popup() {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
LayoutInflater inflater = (LayoutInflater) Login.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.connection_popup,
(ViewGroup) findViewById(R.id.conn_pop));
// create a 300px width and 470px height PopupWindow
final PopupWindow pw = new PopupWindow(layout,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, true);
// display the popup in the center
pw.showAtLocation(layout, Gravity.CENTER, 0, 0); // this is where i'm getting the Exception
}
});
}
我刚做了很多尝试:
用:{/ p>替换inflater
getWindow().addContentView(layout,new ViewGroup.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)); // after declaring the Layout View of course
将上下文(Login.this
)更改为:
1- getApplicationContext()
。
2- getBaseContext()
。
3-创建一个Application
类来检索当前称为所需方法的上下文(MyApplication.getAppContext()
)。正如here所述。
答案 0 :(得分:3)
不是将弹出功能创建到活动本身,而是尝试为它创建单独的活动,当互联网连接消失时,调用此活动,并在将该活动声明为android清单文件时使用以下标记
android:theme="@style/Theme.Transparent"
这样即使您没有进入申请,也不会收到错误
答案 1 :(得分:2)
为什么不注册广播接收器,当连接丢失时会通知您?它会比现在更容易。
private final BroadcastReceiver connectionStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!isNetworkAvailable(context)) {
init_conn_lost_popup();
}
}
}
privaate boolean isNetworkAvailable(final Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
现在只需在onResume()
方法中注册此接收器,同时在onPause()
答案 2 :(得分:0)
//Declare your AlertDialog here
private AlertDialog alertDialog;
.....
.....
//Your Broadcasr receiver in Mainactivity for connection change info
private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
try {
if (alertDialog != null && alertDialog.isShowing())
alertDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
if (alertDialog == null || !alertDialog.isShowing()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
//Define your custom layout here
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_networl_lost, null);
builder.setView(dialoglayout);
builder.setCancelable(false);
alertDialog = builder.create();
alertDialog.show();
}
}
}
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if (networkReceiver != null)
unregisterReceiver(networkReceiver);
}