Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(android): Back button fix for SDK28 #225

Closed
wants to merge 1 commit into from

Conversation

prageeth
Copy link

@prageeth prageeth commented Jul 2, 2019

Platforms affected

Android

Motivation and Context

Fixes #186

Description

Back button not working correctly on Android for SDK28, more details in the linked issue.

Checklist

  • Commit is prefixed with (platform) if this change only applies to one platform (e.g. (android))
  • If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct keyword to close issues using keywords)

@prageeth
Copy link
Author

prageeth commented Jul 2, 2019

@timbru31 Any chance this can be reviewed and merged? This PR was created since the other one went silent: #187

@janpio janpio changed the title (android) Back button fix for SDK28 fix(android): Back button fix for SDK28 Jul 2, 2019
@prageeth
Copy link
Author

prageeth commented Jul 2, 2019

@janpio Travis CI seems to be failing for an unrelated reason. Would this be a blocker for merging this PR? Thanks for your help :)

@janpio
Copy link
Member

janpio commented Jul 2, 2019

Yes, but I can fix that in a minute. 🕙

@janpio janpio closed this Jul 2, 2019
@janpio
Copy link
Member

janpio commented Jul 2, 2019

And reopen so that Travis tries to build a merge to the now fixed master.

@janpio janpio reopened this Jul 2, 2019
@prageeth
Copy link
Author

prageeth commented Jul 2, 2019

@janpio I'm assuming the pipeline is blocked for some reason? Any chance we can get this merged in the next day or two? Thanks!

@janpio
Copy link
Member

janpio commented Jul 2, 2019

The builds will run, just takes "some" time (unfortunately out of our control).

And no, no guarantee when this will be merged. But as we just did a release, it won't be quick after the merge to be released anyway. We'll have to do some cleanup of issues an Pull Requests first.

@prageeth
Copy link
Author

prageeth commented Jul 2, 2019

@janpio Thanks for the update, I might use my fork in the mean time as it's blocking my app releases.

@EnRyYyYy
Copy link

EnRyYyYy commented Jul 3, 2019

I have same problem. Any plan to release this fix soon?
Tnx

@janpio
Copy link
Member

janpio commented Jul 3, 2019

See #225 (comment) @EnRyYyYy

@bnfrnz
Copy link

bnfrnz commented Jul 5, 2019

This does NOT fix the issue for me. I am running an Ionic 3 app and it only seems to fix the issue when I'm on navigation root level. As soon as I push a page onto the nav stack and use the hardware back button, the app activity is still being destroyed. When reopening the app, it restarts completely.

Has someone actually done a root cause analysis or how did this fix come about? There are a fair few breaking changes in Android 9. It may have something to do with one of those.

@janpio
Copy link
Member

janpio commented Jul 5, 2019

@bnfrnz Unfortunately the original bug report #186 doesn't contain too much information on what exactly is going wrong besides "not working", so it's difficult to evaluate if this is the same problem. Can you create a quick reproduction app using Ionic and put it on GitHub?

@bnfrnz
Copy link

bnfrnz commented Jul 5, 2019

OK, I'll try to find time this weekend. Basically, it's an [email protected] app with [email protected]. I use registerBackButtonAction as always but when using Target SDK 28, instead of executing my function, the entire app activity is killed.

When using a lower Target SDK, there's no issue. I have no idea whether this is even caused by the splashscreen plugin. I just ended up in this repo from here.

Looking at the proposed fix though, I'm not sure I understand what the assumed root cause was and how the fix addresses it. It seems a bit like a random trial-and-error workaround. But maybe I'm missing something.

@bnfrnz
Copy link

bnfrnz commented Jul 6, 2019

@janpio, I've figured out why my app is still crashing. I am using another plugin (NativePageTransitions) that also calls the function View#setVisibility(int). So, I can confirm that running this function (on UI thread or not) is indeed causing the issue.

This "fix" basically just prevents the plugin from calling the function when running on API level 28 or higher. This isn't really a fix, right? I'm sure there was a point to calling that function...

I've been trying to find out why on API level 28 it suddenly seems to be an issue to run setVisibility from a cordova activity, with no luck. I have zero experience with plugin/Android development. Maybe someone with experience could look into this and find out what should be used instead of setVisibility so we can replace it instead of simply deleting it.

@janpio
Copy link
Member

janpio commented Jul 6, 2019

The code has been there since the pplugin was created in 2014 when the splashscreen functionality was extracted from cordova-android: 50e4887#diff-bb81295a5f916476389a7a0213be0498R55

As I understand it, the webview is hidden / made invisible when the splashscreen is initially shown. Later on hiding the spinner (!?), it is made visible again. As the splash is over the webview anyway, this probably is not really necessary - and so this fix here "works".

My total ad hoc theory: Since API level 28 the webview has to be visible for the back button handler to be initialized, or making it invisible changes its characteristics in some other way. But as my Android is pretty rudimentary as well, no real idea.

@janpio
Copy link
Member

janpio commented Jul 6, 2019

Found where this code was initially added: apache/cordova-android@21a34a8#diff-f0fbc2da5463e5a0ada4128307a33c33R237 - 2011! So this is a really old part of cordova-android. Later when the splashscreen plugin was extracted from it, this code came with it.

@bnfrnz
Copy link

bnfrnz commented Jul 6, 2019

OK, great. Good to hear that this is a fix then in case of this plugin.

Guess I'll need to somehow figure out what to do with the other plugin as I need those native page transitions. Unfortunately that plugin isn't maintained anymore.

@ all, if anyone has an idea as to why setVisibility is the issue here and how to overcome it, please share. Thanks!

@janpio
Copy link
Member

janpio commented Jul 6, 2019

(To be honest I don't fully understand where this visibility thing is undone,

@Override
public Object onMessage(String id, Object data) {
if (HAS_BUILT_IN_SPLASH_SCREEN) {
return null;
}
if ("splashscreen".equals(id)) {
if ("hide".equals(data.toString())) {
this.removeSplashScreen(false);
} else {
this.showSplashScreen(false);
}
} else if ("spinner".equals(id)) {
if ("stop".equals(data.toString())) {
getView().setVisibility(View.VISIBLE);
}
doesn't really like the correct one - or at least I don't understand how/why this would be triggered - but it is the only one I can find)

Guess I'll need to somehow figure out what to do with the other plugin as I need those native page transitions. Unfortunately that plugin isn't maintained anymore.

Fork it :/

@bnfrnz
Copy link

bnfrnz commented Jul 7, 2019

doesn't really like the correct one - or at least I don't understand how/why this would be triggered - but it is the only one I can find)

@janpio Yep, I think you're right. When the loading spinner stops, the webview is shown again and then the splash is removed.

Fork it :/

The thing is that the native page transitions plugin does actually need to set the visibility before and after every page transition. May just have to switch to using CSS animations...

@MBuchalik
Copy link

What would happen if the code for hiding the WebView was removed for all Android versions? So why does it even exist?

@janpio
Copy link
Member

janpio commented Jul 16, 2019

You tell me ;) See #225 (comment)

@MBuchalik
Copy link

As far as I can see in the code sample from 2011, the WebView was made invisible in all cases (not only when the Splash Screen was active).

I cannot find any reason why it exists in this PR: apache/cordova-android#134 or here: 50e4887

So to me, it remains unclear why it has been made. My problem is that I have nearly no experience in Android development, so maybe I simply don't yet know a certain important concept here.

Is any of the authors of the commits mentioned above still active? Maybe, we could ask them...

@juanludukeboss
Copy link

Hi guys,
this problem is solved in the commit of may 2019. View link: 05d8f9a

So, is not suficient only modify the file "SplashScreen.java" from directory "plugins" of our project cordova. After, is necesary copy this file in all locations inside directory "platforms/android".
When the changes is ready, build your project android and deploy in Android 9, now the back button is working correctly. I'm testing in old version of Android and also working perfectly.

I'm very happy, problem solved. :)

@janpio
Copy link
Member

janpio commented Jul 26, 2019

This PR where you commented is for that commit @juanludukeboss - but the problem is we don't know if this has any side effects and nobody could explain why it is necessary, which is why we are hesitant to just merge this.

@juanludukeboss
Copy link

What you say will be difficult to know beforehand. You will have to update your plugin and test the result. This is much better than the Back button is failing. I can to see that my Splash loads perfectly, just started the App and when it is suspended also.

So, I don't see nothing bad. All working perfect in Android 9 and old versions.

Regards.

@VisualMafia
Copy link

Hi guys,
this problem is solved in the commit of may 2019. View link: 05d8f9a

So, is not suficient only modify the file "SplashScreen.java" from directory "plugins" of our project cordova. After, is necesary copy this file in all locations inside directory "platforms/android".
When the changes is ready, build your project android and deploy in Android 9, now the back button is working correctly. I'm testing in old version of Android and also working perfectly.

I'm very happy, problem solved. :)

I add this, cordova build error

@heidji
Copy link

heidji commented Jul 29, 2019

What you say will be difficult to know beforehand. You will have to update your plugin and test the result. This is much better than the Back button is failing. I can to see that my Splash loads perfectly, just started the App and when it is suspended also.

So, I don't see nothing bad. All working perfect in Android 9 and old versions.

Regards.

Same thought here. I guess we have fork that commit into our projects until the maintainers decide on a solution

@VisualMafia
Copy link

VisualMafia commented Jul 30, 2019

What you say will be difficult to know beforehand. You will have to update your plugin and test the result. This is much better than the Back button is failing. I can to see that my Splash loads perfectly, just started the App and when it is suspended also.
So, I don't see nothing bad. All working perfect in Android 9 and old versions.
Regards.

Same thought here. I guess we have fork that commit into our projects until the maintainers decide on a solution

I remove plugin. Add plugin this fork (https://github.com/prageeth/cordova-plugin-splashscreen.git). Error if build android:

... SplashScreen.java:101: error: cannot find symbol
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
^
symbol: variable P
location: class VERSION_CODES

@juanludukeboss
Copy link

Hi, if you have this error

What you say will be difficult to know beforehand. You will have to update your plugin and test the result. This is much better than the Back button is failing. I can to see that my Splash loads perfectly, just started the App and when it is suspended also.
So, I don't see nothing bad. All working perfect in Android 9 and old versions.
Regards.

Same thought here. I guess we have fork that commit into our projects until the maintainers decide on a solution

I remove plugin. Add plugin this fork. Error if build android.

For remove this error when you build Android you need put in your file "config.xml" from your Cordova project the attribute xmlns:android="http://schemas.android.com/apk/res/android" in the node "widget".

Attach example of my project
Captura de pantalla 2019-07-30 a las 14 51 57

@juanludukeboss
Copy link

What you say will be difficult to know beforehand. You will have to update your plugin and test the result. This is much better than the Back button is failing. I can to see that my Splash loads perfectly, just started the App and when it is suspended also.
So, I don't see nothing bad. All working perfect in Android 9 and old versions.
Regards.

Same thought here. I guess we have fork that commit into our projects until the maintainers decide on a solution

I remove plugin. Add plugin this fork. Error if build android.

For remove this error when you build Android you need put in your file "config.xml" from your Cordova project the attribute xmlns:android="http://schemas.android.com/apk/res/android" in the node "widget".

Attach example of my project
Captura de pantalla 2019-07-30 a las 14 51 57

@VisualMafia
Copy link

VisualMafia commented Jul 30, 2019

For remove this error when you build Android you need put in your file "config.xml" from your Cordova project the attribute xmlns:android="http://schemas.android.com/apk/res/android" in the node "widget".

Works, thanks

@pliablepixels
Copy link

pliablepixels commented Aug 18, 2019

I've just landed up with the same issue after updating my target Sdk to Android 28.
Just updating cordova-splash-screen to 5.0.3 doesn't make a difference. Just wanted to make sure the only solution as of now is to switch to https://github.com/prageeth/cordova-plugin-splashscreen.git ?

(Updated: Confirmed that using the fork fixes this issue. Also note that for folks facing this error (as reported above):

... SplashScreen.java:101: error: cannot find symbol
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
^
symbol: variable P
location: class VERSION_CODES

It is not sufficient just to add xmlns:android="http://schemas.android.com/apk/res/android" to config.xml (I already had it on). I had to update cordova-android to 8.0.0 (I was at 7.1.4)

@ebhsgit
Copy link

ebhsgit commented Sep 17, 2019

@janpio @prageeth
I believe the fix is in the right direction, but I don't believe the fix is quite right.
In an ionic app, the fix incorrectly prevents popping of page.

I've created a sample project that uses prageeths fork.
sample project

Steps

  1. send text (to anyone) with https://demoapp.com/L/items/2
  2. In your texting app, click the link
  3. App opens into 2 level deep. (Items -> Items Detail)
  4. Use hardware back button
  5. Notice the back button does not pop to root

@juanludukeboss
Copy link

I have 3 apps in production with my solution and all working ok in Android 9 and old versions. My solution is very simple and working perfectly

@ramyzbeidy
Copy link

But this now shows the application before its loaded? Are you facing this issue?

@ebhsgit
Copy link

ebhsgit commented Oct 17, 2019

@janpio @prageeth
I believe the fix is in the right direction, but I don't believe the fix is quite right.
In an ionic app, the fix incorrectly prevents popping of page.

I've created a sample project that uses prageeths fork.
sample project

Steps

  1. send text (to anyone) with https://demoapp.com/L/items/2
  2. In your texting app, click the link
  3. App opens into 2 level deep. (Items -> Items Detail)
  4. Use hardware back button
  5. Notice the back button does not pop to root

Correction to my comment. The workaround is not the of the issue.

After further debugging. The issue with "not popping" back to root is to do with the the deeplink code.

@Birowsky
Copy link

Birowsky commented Dec 4, 2019

Just came to confirm that this fork is working for me.

@IntellectBizMobility
Copy link

IntellectBizMobility commented Dec 12, 2019

@janpio @prageeth
Not Working

I have an ionic project and have imported the plugin from the mentioned fork. Still having the same issue except for the first screen its working fine. Do we need to write back button handling in every page? or in just app.component? Please suggest.

@IntellectBizMobility
Copy link

Thanks @bnfrnz . I was also having the same issue. Once the native transition plugin is removed and the new plugin for splashscreen installed, its working fine. But can anyone tell what is the permanent solution for this issue. coz I need Native Transition Plugin to be installed.

@bnfrnz
Copy link

bnfrnz commented Dec 12, 2019

@IntellectBizMobility, we needed custom page transitions as well and ended up writing them ourselves using CSS animations.

Here an example for a vertical slide:

import { Animation } from 'ionic-angular/animations/animation';
import { PageTransition } from 'ionic-angular/transitions/page-transition';
import { isPresent } from 'ionic-angular/util/util';

export class VerticalSlideTransition extends PageTransition {
	init(): void {
		try {
			super.init();
			this.duration(isPresent(this.opts.duration) ? this.opts.duration : 500); //Default duration: 500mms
			this.easing(isPresent(this.opts.easing) ? this.opts.easing : 'ease-in-out'); //Default easing: ease-in-out

			// Push transition:
			if (this.opts.direction === 'forward') {
				if (this.enteringView) {
					const enteringContent: Animation = new Animation(this.plt, this.enteringView.pageRef());
					this.add(enteringContent.fromTo('translateY', '100%', '0', true));
				}
				if (this.leavingView && this.leavingView.pageRef()) {
					const leavingContent: Animation = new Animation(this.plt, this.leavingView.pageRef());
					this.add(leavingContent.fromTo('translateY', '0', '0', true));
				}
			}

			// Pop transition:
			else if (this.opts.direction === 'back') {
				if (this.enteringView) {
					const enteringContent: Animation = new Animation(this.plt, this.enteringView.pageRef());
					this.add(enteringContent.fromTo('translateY', '0', '0', true));
				}
				if (this.leavingView && this.leavingView.pageRef()) {
					const leavingContent: Animation = new Animation(this.plt, this.leavingView.pageRef());
					this.add(leavingContent.fromTo('translateY', '0', '100%', false));
				}
			}
		} catch (err) {
			console.error(err);
		}
	}
}

Then, in your app.component.ts register your transition to your config:

this.config.setTransition('vertical-slide', VerticalSlideTransition);

And then use it like so:

const navOpts: NavOptions = {
	animation: 'vertical-slide',
	direction: 'forward',
	duration: 400,
	easing: 'ease-in-out'
};
this.navCtrl.push('NewPage', navParams, navOpts);

You can pretty much build whatever transition you want. It's really just CSS animations wrapped in JavaScript.

In theory, they may be less performant than the native transitions but we didn't see any issues with newer phones.

As far as I remember, the native page transitions plugin isn't being maintained anymore, so we were actually happy to remove it, as keeping it just promises more issues down the road. The whole Cordova ecosystem is quite bad in that a lot of plugins (even really basic ones like this splash screen) aren't maintained properly. And frameworks like Ionic 3 (who are reliant on Cordova plugins and claim to offer a "curated" set of them) don't do anything about it either. I mean, it's free... and that's great... but it's also quite pointless if every other time some library is being updated something breaks and no one fixes it.

@NiklasMerz
Copy link
Member

Should be solved with 66d1e00

@NiklasMerz NiklasMerz closed this Apr 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Android 9 - target SDK 28] Backbutton not working