WindowLeaked issue - java

I am having a big problem with WindowLeaked:
E/WindowManager: android.view.WindowLeaked: Activity CrearGrupo has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{3702bf39 V.E..... R....... 0,0-960,883} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:298)
at es.uva.tel.gco.CrearGrupo$2.onClick(CrearGrupo.java:175)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Here the code:
final Dialog dialog2 = new Dialog(activity, R.style.dialog);
tituloDialogo=res.getString(R.string.crearGrupoDiálogo);
dialog2.setTitle(tituloDialogo +" "+listaAsignaturas.get(pos));
dialog2.setContentView(R.layout.prefijo_grupo);
if (control == 0){
//listNotebooks(pos);
Intent intent=new Intent(getApplicationContext(),MostrarCrearGrupos.class);
intent.putExtra("asignatura",listaAsignaturas.get(pos));
intent.putExtra("prefijo",prefGrupo.getText().toString());
intent.putExtra("nombreLibreta",notebookName);
startActivity(intent);
}
}
});
dialog2.show();
Dialog is a normal window with 2 inputs that let you enter one name and 1 prefix but when I try to show another dialog the app crash.
I already look for a solution and try to solve it with:
#Override
public void onDestroy() {
super.onDestroy();
if (dialog2 != null) {
dialog2.dismiss();
dialog2 = null;
}
}
#Override
protected void onPause(){
super.onPause();
if (dialog2 != null) {
dialog2.dismiss();
dialog2 = null;
}
}
#Override
protected void onStop(){
super.onStop();
if (dialog2 != null) {
dialog2.dismiss();
dialog2 = null;
}
}
But it doesnt work. Any ideas.
Thx for your answers. :)

In you case, you are try to call dialog2.show() after starting the new activity. Remove that and your code will work.
Here is the main reason why Leaked windows error occurs:
We know that every Activity Android has an WindowManager window manager, likewise, is built on top of a Activity dialog box, PopupWindow also has the corresponding WindowManager window manager. Because the dialog box, the PopupWindown from the Activity and should not exist alone, So when a Dialog or a PopupWindow is displayed when we go to finish () carrying the Dialog (or PopupWindow) Activity, Window Leaked exception will be thrown., Because the Dialog (or PopupWindow) WindowManager have who can not affiliated., So the window manager it has leaked.
Android.view.WindowLeaked usually occur in the display of Activity and Dialog.
Create Activity in a Dialog, and if you turn off Dialog first and then close the Activity is normal, if you shut down the Activity first and then close the Dialog will error the error android.view.WindowLeaked.
Analysis the reason is: Dialog is created based on Activity: new ProgressDialog (this); this is Activity. Activtity finish first, then Dialog will have no attachment, so will report android.view.WindowLeaked.

Related

Alert dialog crashes android app if i keep it open when i close the phone (Activity leaking)

so I'm looking to create an application to control an arduino car , and i have a alert dialog that pops-up when i click a button , until here , everything works with no problems .
But here i have a special thing , when I open the alert dialog by pressing it's button and let's say i press the power button to close my phone , my app crashes , and i tried a lot of things like PowerManager and stuff like that , but it didnt work
So here is the code for the Alert dialog :
void dialogCreater() {
final AlertDialog.Builder mbuilder = new AlertDialog.Builder(CarActivity.this);
View mView = getLayoutInflater().inflate(R.layout.settings, null);
final EditText editForward = mView.findViewById(R.id.editForward);
final EditText editBackwards = mView.findViewById(R.id.editBackwards);
final EditText editLeft = mView.findViewById(R.id.editLeft);
final EditText editRight= mView.findViewById(R.id.editRight);
final EditText editForwardLeft = mView.findViewById(R.id.editForwardLeft);
final EditText editForwardRight = mView.findViewById(R.id.editForwardRight);
final EditText editBackwardsLeft = mView.findViewById(R.id.editBackwardsLeft);
final EditText editBackwardsRight = mView.findViewById(R.id.editBackwardsRight);
final EditText editStop = mView.findViewById(R.id.editStop);
Button mAccept = mView.findViewById(R.id.btnAccept);
Button mCancel = mView.findViewById(R.id.btnCancel);
Button mDefaultSettings = mView.findViewById(R.id.btnDefault);
mbuilder.setView(mView);
dialog = mbuilder.create();
dialog.setCancelable(true);
// a few buttons for the dialog
dialog.show();
Ok so this is the code , and my application crashes at the line from above (dialog.show()) when the dialog is opened and i close the phone
This is the error I am getting :
E/WindowManager: android.view.WindowLeaked: Activity com.example.edi.bluetoothgoogleplay.CarActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{5954400 V.E..... R....... 0,0-832,670} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:298)
at com.example.edi.bluetoothgoogleplay.CarActivity.dialogCreater(CarActivity.java:624)
at com.example.edi.bluetoothgoogleplay.CarActivity$12.onClick(CarActivity.java:383)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19761)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5264)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
So if anyone could help me , anything would be apreciated !

Activity has leaked window PopupWindow after rotation

When I rotate my device while showing a PopupMenu, I get a WindowLeaked error.
That's my PopupMenu:
private void showSelectionMenu(View caller) {
popup = new PopupMenu(this, caller);
// popup.getMenuInflater().inflate(R.menu.selection_menu, popup.getMenu());
popup.inflate(R.menu.selection_menu);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(FileListActivity.this, getString(R.string.selecting)+" "+item.getTitle(), Toast.LENGTH_SHORT).show();
switch (item.getItemId()) {
case R.id.select_all: mediaFolder.selectAll(); break;
case R.id.select_none: mediaFolder.selectNone(); break;
case R.id.select_videos: mediaFolder.selectVideos(); break;
case R.id.select_pictures: mediaFolder.selectImages(); break;
default: break;
}
findViewById(R.id.buttonRenameSelected).setEnabled(mediaFolder.numberSelected>0);
cla.redraw();
return true;
}
});
if (Build.VERSION.SDK_INT >= 14) {
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
#Override
public void onDismiss(PopupMenu menu) {
Log.d(TAG, "selectionMenu dismissed");
}
});
}
popup.show();
}
I know that many programmers here had the same error before and usually they are told to dismiss the menu in onDestroy(). So do I:
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "FileListActivity onDestroy()");
Log.d(TAG, "onDestroy: popup==null? "+(popup==null));
if (popup != null) { popup.dismiss(); popup = null; }
Log.d(TAG, "onDestroy: popup==null? "+(popup==null));
dataFragment.mRetainedCache = mMemoryCache;
dataFragment.setData(mediaFolder);
}
And that's the resulting log including the error:
02-10 22:24:15.969 D: FileListActivity onDestroy()
02-10 22:24:15.969 D: onDestroy: popup==null? false
02-10 22:24:15.971 D: selectionMenu dismissed
02-10 22:24:15.971 D: onDestroy: popup==null? true
02-10 22:24:16.064 E: android.view.WindowLeaked: Activity com.myApp.FileListActivity has leaked window android.widget.PopupWindow$PopupDecorView{365b288 V.E...... ......ID 0,0-822,1152} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1378)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:1234)
at android.support.v7.widget.AppCompatPopupWindow.showAsDropDown(AppCompatPopupWindow.java:78)
at android.support.v4.widget.PopupWindowCompatKitKat.showAsDropDown(PopupWindowCompatKitKat.java:30)
at android.support.v4.widget.PopupWindowCompat$KitKatPopupWindowImpl.showAsDropDown(PopupWindowCompat.java:92)
at android.support.v4.widget.PopupWindowCompat.showAsDropDown(PopupWindowCompat.java:171)
at android.support.v7.widget.ListPopupWindow.show(ListPopupWindow.java:680)
at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:163)
at android.support.v7.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:129)
at android.support.v7.widget.PopupMenu.show(PopupMenu.java:216)
at com.myApp.FileListActivity.showSelectionMenu(FileListActivity.java:434)
at com.myApp.FileListActivity.access$100(FileListActivity.java:44)
at com.myApp.FileListActivity$5.onClick(FileListActivity.java:186)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22433)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6126)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
02-10 22:24:16.079 D: FileListActivity onCreate()
As you can see in the log, the PopupMenu (popup) is dismissed and set to null before the error occurs.
Any idea what's going wrong?
EDIT:
That's where showSelectionMenu(View caller) is called (in onCreate):
Button buttonSelectFiles = (Button) findViewById(R.id.buttonSelectFiles);
buttonSelectFiles.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showSelectionMenu(v);
}
});
EDIT 2:
I just found out that I get that error on my Nexus 5 running Android 7.1.1 (LineageOS, nightly build) but not on a Fire HD 8 running Fire OS 5.3.2.1 (based on Android 5) and not either on a Samsung Galaxy S+ running Android 4.4.4 (CyanogenMod 11). So maybe it only happens on Android 7 or maybe there is a bug in LineageOS!?
If anybody has an official Android 7, he/she could try to provoke that error using this Android Popup Menu Example. You only would have to add this code:
#Override
public void onDestroy() {
super.onDestroy();
if (popup != null) { popup.dismiss(); popup = null; }
}
and make popup a class member variable.
EDIT 3:
It's not a LineageOS problem. This error also occurs in the Android Studio Emulator running Android 7.1.1.
Error is occured when your code tries to show popup. Activities are recreated after rotation change so I think your caller parameter contains a View from the activity destroyed. You should check where caller parameter comes from and reassign if necessary.

Why is dialog.show() causing my app to crash?

I've been trying to get a dialog message to work on android and the app always crash when it reaches "dialog.show();"
public class Logic extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle("Alarm");
dialogBuilder.setMessage(messageActivity.getMes());
dialogBuilder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog dialog = dialogBuilder.create();
dialog.show();
}
}
Here is my logcat:
FATAL EXCEPTION: main
Process: it226.myapplicationit226androidapp, PID: 19598
java.lang.RuntimeException: Unable to start receiver it226.myapplicationit226androidapp.Logic: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:571)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:319)
at it226.myapplicationit226androidapp.Logic.onReceive(Logic.java:65)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2725)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
You can't create dialog from receiver.
Creating dialogs is allowed only from UI components (which have looper).
You could start transparent activity with dialog, which would be the same for user.
You can't create a dialog using the context of a BroadcastReceiver, you has two options to solve this problem:
first one is to create a regular Activity which has only the size of the dialog as a shown part and the full remaining is transparent:
Intent newIntent = new Intent(context, Displayer.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
second one is to hold your Activity context and then use it in creating the dialog, but at this method you have to make sure what is the activity that is currently open:
// in your activity onCreate
ctx = YourActivity.this; // let's suppose ctx is static and general var
////////////////////////////////////////////////
// in the BroadcastReceiver
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(YourActivity.ctx);

Android removeView crashed

I'm creating a screen lock app, and faced notification able to drag down in the lock screen.
I've research it and found this solution to block the notification bar by using addView code below, but I cannot remove the view after user unlocked my app. Please advice how to remove the view.
I've try to use manager.removeView(view); in public void onDestroy() { but it crashed after run this code.
This is the error message
FATAL EXCEPTION: main
Process: com.mehuljoisar.lockscreen, PID: 10256
java.lang.IllegalArgumentException: View=android.view.View{42348cc0 V.ED.... ........ 0,0-0,0} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:373)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:302)
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:79)
at com.mehuljoisar.lockscreen.LockScreenActivity.disablePullNotificationTouch(LockScreenActivity.java:261)
at com.mehuljoisar.lockscreen.LockScreenActivity.access$100(LockScreenActivity.java:24)
at com.mehuljoisar.lockscreen.LockScreenActivity$2.onClick(LockScreenActivity.java:113)
at android.view.View.performClick(View.java:4469)
at android.view.View$PerformClick.run(View.java:18788)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5347)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:835)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:651)
at dalvik.system.NativeStart.main(Native Method)
Where should I put the removeView code?
private void disablePullNotificationTouch(String gg) {
WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP; //make the line top
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height = (int) (25 * getResources().getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.RGBX_8888;
View view = new View(this);
if(gg == "on") {
manager.addView(view, localLayoutParams);
}else {
manager.removeView(view);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
disablePullNotificationTouch("on");
}
#Override
public void onDestroy() {
super.onDestroy();
disablePullNotificationTouch("off");
}
You use
WindowManager manager = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE));
Not use
WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
Try it!

Button to set different activity colour

I am trying to set the background colour of a different activity from the activity main but I am getting a null pointer.
This is the main:
View activity;
activity = findViewById(R.layout.activity_connect_four);
The button:
Button highScoreButton1 = (Button) findViewById(R.id.bgc);
highScoreButton1.setOnClickListener(new OnClickListener() {
public void onClick (View v) {
// null pointer on below line
activity.findViewById(android.R.id.content)
.setBackgroundColor(Color.BLACK);
}
});
The logcat:
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.con4.MainActivity$4.onClick(MainActivity.java:80)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Where the logCat is pointing to, I don't know what to change. Any help I would be grateful
You're receiving a NPE because that activity and view is not inflated, therefore it returns as null. The way you're setting the background color is flawed by nature. By setting it as you are, even without the NPE, you're storing a setting in the memory of the device. The moment that the device kills your activity, you'll lose that information. As an alternative, you need to store this setting on the device for later retrieval. For what you're attempting to do, I would recommend using SharedPreferences.
In your settings Activity:
Button highScoreButton1 = (Button) findViewById(R.id.bgc);
SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
highScoreButton1.setOnClickListener(new OnClickListener() {
public void onClick (View v) {
prefs.edit().putInt(BACKGROUND_COLOR, Color.BLACK).commit();
}
});
BACKGROUND_COLOR is a key variable that could be set to "background_color". Then when you start you other activity:
SharedPreferences prefs = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
int color = prefs.getInt(BACKGROUND_COLOR, Color.WHITE);
And use that color to set the background. Using this method, the background color will be saved to the device until it gets overridden (settings change) or the app is uninstalled.
If you want this to be the background of all of your activity, I suggest having all activities extending a base activity and implementing that code there.
You can check out other storage methods here: http://developer.android.com/guide/topics/data/data-storage.html

Categories

Resources