{ "id": "171291", "key": "TIMOB-25857", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": null, "resolutiondate": null, "created": "2018-03-12T10:58:31.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "android", "fragmentation", "splash-screen" ], "versions": [ { "id": "19957", "description": "", "name": "Release 7.1.0", "archived": false, "released": true, "releaseDate": "2018-03-14" } ], "issuelinks": [], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2019-06-14T17:30:57.000+0000", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" }, { "id": "10207", "name": "Tooling" } ], "description": "Right now for splash screens on android we add an activity in front of the app that displays the image. However, this image is fixed in size and when a photo is to be used as a splash screen a 9-patch image is not a solution.\r\n\r\nInstead, the image should not be stretching as was also asked on StackOverflow: https://stackoverflow.com/a/37616137/249710\r\n\r\nThe solution there is to change the activity with an ImageView and use the center-crop method. This will prevent stretching of the image.\r\n\r\n{code}\r\n\r\n\r\n \r\n\r\n{code}\r\n\r\n*Expected Result*\r\nThe image should not stretch but center crop instead. This will prevent any stretching and will allow the user to use photos as splash screens.", "attachment": [], "flagged": false, "summary": "Android: Prevent stretching splash screen", "creator": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "topener", "key": "topener", "displayName": "Rene Pot", "active": true, "timeZone": "Europe/Berlin" }, "environment": "TiSDK 7.1.0.GA\r\nAlloy 1.11\r\nAndroid", "closedSprints": [ { "id": 1008, "state": "closed", "name": "2018 Sprint 06 SDK", "startDate": "2018-03-11T22:18:04.396Z", "endDate": "2018-03-25T22:18:00.000Z", "completeDate": "2018-03-25T21:52:36.683Z", "originBoardId": 216 } ], "comment": { "comments": [ { "id": "435478", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "Changing the activity in the Titanium SDK would be great, another improvement could be that, for example, Titanium searches if there is a _*activity_splash.xml*_ available under _*/platform/android/res/layout*_ and if so, set the contentView to this activity. If not, show the standard splash screen with the _*default.png*_ background.\r\n\r\nUsing this approach makes it possible to create a separate, custom splash screen activity. This enabled full control to developer about the look and feel of the splash screen.", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-12T11:56:01.000+0000", "updated": "2018-03-12T11:57:39.000+0000" }, { "id": "435496", "author": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "body": "I agree with Joren that a custom activity would be nice. Our stakeholders want to put a dynamic ad unit onto the splash screen, which we can't do currently.\r\n\r\nBut please don't hold up the entire JIRA issue for that. The centerCrop would fix a lot of problems, and it would do that with minimal effort. We could use this feature right away!", "updateAuthor": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "created": "2018-03-12T17:01:26.000+0000", "updated": "2018-03-12T17:01:26.000+0000" }, { "id": "435500", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-12T17:26:45.000+0000", "updated": "2018-03-12T17:29:59.000+0000" }, { "id": "435501", "author": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "body": "Makes sense to provide the option!", "updateAuthor": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "created": "2018-03-12T17:32:38.000+0000", "updated": "2018-03-12T17:32:38.000+0000" }, { "id": "435519", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "Joshua,\r\n\r\nBest way to solve the issues you're mentioning is by implementing it the way I proposed. \r\n\r\nWhen providing the possibility to set a custom splash screen, this gives the developer a lot of freedom:\r\n- The developer wants to show a copyright not on the bottom of the screen? Right, add a label at the bottom of the activity.\r\n- I need to have an image as a background and a centered company logo? Fine, I can add a fullscreen imageview for the background and another imageview above the first one for the logo.\r\n\r\nThe proposed option to just let the user set \"stretch\", \"crop\", \"letterbox\" etc are also less \"customizable\" for the developer. If you let the user decide these properties in the tiapp.xml, it won't be that large effort to let the user provide the name for a custom splash screen activity that he puts in the platform/android/layout folder? When launching the app, just check if the provided layout exists in the path and if so, setContentView to this layout...?\r\n\r\nI hope you understand my concern about the importance of the possibility to create a custom splash screen activity. As a developer, I need to have the possibility to make my own decisions. If the only possibility for me would be to set the \"stretch\", \"crop\" etc, then in a few weeks I need to create a new feature request to have custom splash screen activity because of the need of an overlaying logo... ", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-12T21:49:42.000+0000", "updated": "2018-03-12T21:51:36.000+0000" }, { "id": "435520", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~jvos], I think it's best to keep it simple.\r\n\r\nIf you want something fully customizable, then you can set the splash to a blank image and create your own splash screen window via our existing Titanium APIs. From there you have far more control and can do more interesting things such as display a progress bar, activity indicator, etc. Doing it this way would also be portable between Android, iOS, and Windows.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-12T22:07:05.000+0000", "updated": "2018-03-12T22:07:05.000+0000" }, { "id": "435521", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "Hi Joshua,\r\n\r\nThanks for your reply, but a blank image is the splash screen...? So I don't get how to create a splash screen via the Titanium API? Because that's after you've shown the user a blank screen for a few seconds...\r\n\r\nI tried some stuff, it should be quite easy to implement with some help of the TiRHelper.getResource(); class...There were many votes for this (simple) alternative instead of pimping the current background image. ", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-12T22:11:06.000+0000", "updated": "2018-03-12T22:11:06.000+0000" }, { "id": "435522", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "On Android, we have what's called a launch activity (ie: our {{TiLaunchActivity.java}}) which is the first activity window that's shown on startup. This is the window that display the splash screen image. You can make the splash a pure all-black image. In your main script, create a Titanium window to display your splash screen window to your liking and switch to a fade transition effect. This will give the appearance of your app's custom splash screen window to have a fade-in effect. However, this is only a good solution if you move your app initialization/loading code to your custom splash window's \"open\" event.\r\n\r\nThis is something I see mobile games do on both Android and iOS, because games like to show a loading startup screen with a progress indicator. On iOS, the \"default.png\" would be your all-black image.\r\n\r\nNot trying to cop-out here.\r\nI'm trying to provide a portable/powerful/productive solution that'll work on all platforms.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-12T22:32:49.000+0000", "updated": "2018-03-12T22:32:49.000+0000" }, { "id": "435524", "author": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "body": "Our experience is that the Ti splash screen on android is up for 3-4 seconds or more. Way too long to leave the screen blank, IMHO.\r\n\r\nAnd I don't think we're doing a terrible amount of work before opening our first window. We deliberately defer loading libraries, making network calls, creating expensive views, etc. until after the first window is opened.\r\n\r\nI did a little comparison between our app on iOS and on android. On iOS, time to first usable information is about 4 seconds. On android, it's about 10 seconds.\r\n\r\nAdmittedly, our first view is a killer -- a webgl view that takes up half the screen along with a webview+canvas that is plotting a graph that is probably 14 megapixels (px, not dp). But the difference is striking.", "updateAuthor": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "created": "2018-03-12T23:26:21.000+0000", "updated": "2018-03-12T23:26:21.000+0000" }, { "id": "435527", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "I'm thinking from the point of view of our customer and the end user.\r\n\r\nOn iOS, I'm currently using my own splashscreen using this property in the plist:\r\nUILaunchStoryboardName\r\nLaunchScreen\r\n\r\nThat's nice, our customer is happy because of the beautiful splashscreen we made. Now we need to tell him that we can not provide the same experience on Android because the framework we're using doesn't allow overriding the splash activity...\r\n\r\nShowing a blank/black screen for a few seconds is unacceptable, that's the whole point of this issue. Currently, there is a stretched default-image. In my opinion, replacing this by a cropped imageview is a \"quick short term\" fix. I'm sure, letting the developer set the contentView of the splash screen would be a better improvement.", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-13T05:59:17.000+0000", "updated": "2018-03-13T05:59:39.000+0000" }, { "id": "435546", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'm pretty sure the loading of the C/C++ libraries is the source of the delay. This is something we can look into the future. Anyways, I hear you.\r\n\r\nI still think the 9-patch splash screen solution we provide is the better solution. This is a feature Google provides. The idea is you can control which parts of the image gets stretched and which parts don't. You would typically stretch the outer edges of the image, which is typically typically a border designed to be stretched (like how 9-patch button image themes work) or solid colors. The advantage is no parts of the image will get clipped due to cropping. The Android SDK comes with a \"draw9patch\" editor tool to help you create this.\r\nhttp://docs.appcelerator.com/platform/latest/#!/guide/Icons_and_Splash_Screens\r\nhttps://developer.android.com/studio/write/draw9patch.html\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-13T18:06:11.000+0000", "updated": "2018-03-13T18:06:11.000+0000" }, { "id": "435547", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "In my case, stretching is _*no option*_ as we’re using a photo as background image and a logo in the middle of the screen. The 9patch option Google provides is a generic option for various reasons, but not for a background. In other native apps, I can create a custom splash screen. That’s what we (myself and many other users) are asking. No 9patch, just a custom activity.", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-13T18:14:14.000+0000", "updated": "2018-03-13T18:14:14.000+0000" }, { "id": "435548", "author": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "body": "Believe me, I tried the 9-patch technique. I worked on it for a full business day. I could never get the image designed by our graphics team to work well. It would work if you had a solid background, but with a photorealistic background, there's just no part of the background that can be stretched without unnatural distortion.\r\n\r\nI could probably get our design team to come up with an alternate design that is more 9-patch friendly, but the center crop seems like such a simple fix that would add a ton of versatility. Then the deluxe solution that Joren is suggesting would take it to another level!", "updateAuthor": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "created": "2018-03-13T18:15:37.000+0000", "updated": "2018-03-13T18:15:37.000+0000" }, { "id": "435744", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Here is an alternate solution that'll work \"today\".\r\n\r\nWe currently provide the ability to override the theme of the splash screen activity as documented in the link below. You can do something similar and override how the background drawable is loaded.\r\nhttps://docs.appcelerator.com/platform/latest/#!/guide/Icons_and_Splash_Screens-section-src-29004897_IconsandSplashScreens-Androidsplashscreenconsiderations\r\n\r\nFirst, modify your \"tiapp.xml\" to override the theme handling like the below. Note that for \".YourappnameActivity\", you'll need to replace the \"Yourappname\" part with your project's name. See the \"AndroidManifest.xml\" under your project's \"build/android\" directory for an example.\r\n{code:xml}\r\n\r\n\r\n\t\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n\r\nIn your project, create a \"./platform/android/res/values\" directory and add file \"custom_theme.xml\" with the following contents. This will override Titanium's \"windowBackground\" handling.\r\n{code:xml}\r\n\r\n\r\n\t\r\n\r\n{code}\r\n\r\nIn your project, create a \"./platform/android/res/drawable\" directory and add file \"background_cropped.xml\" with the following contents. This will center the \"background.png\" splashscreen image your have instead of stretching, allowing the image to exceed the bounds of the screen. The 1st item in the layer-list will also render whatever color you want in for the parts around the image in case it's smaller than the screen.\r\n{code:xml}\r\n\r\n\r\n\t\r\n\t\r\n\t\t\r\n\t\r\n\r\n{code}\r\n\r\nNote that the above won't scale the image. It renders it as-is. So, it's not quite the same as the \"cropCenter\" scaling that Rene is requesting, but it may give you the effect you're looking for. There are other bitmap \"gravity\" settings you can play with as can be seen in the link below. And the above layer-list gives you the ability add other drawable types on top.\r\nhttps://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html#attr_android:gravity\r\n\r\nThe bitmap drawable also supports a \"tileMode\" feature as well, which allows you to duplicate an image pattern over the entire view, without scaling. This isn't appropriate for photos, but displaying a tiled background is a cheaper solution memory-wise for low-end Android devices.\r\nhttps://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html#attr_android:tileMode", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-20T03:17:23.000+0000", "updated": "2018-03-20T03:24:26.000+0000" }, { "id": "435804", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "Joshua, I'm not going to spend more words on it again: *I'm using a photo as a background*.\r\n\r\nI tried the workaround you provided, but as you're mentioning, it's not the best solution for using photos. Instead of difficult workarounds, give us (the developer) freedom about the Splash screen as I am able to have on iOS by providing a storyboard.\r\n\r\nAndroid doesn't have a splashscreen out of the box, so this is something Titanium introduced. It's not that hard to give us the possibility to override the splash activity I think?", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-21T15:39:00.000+0000", "updated": "2018-03-21T15:39:17.000+0000" }, { "id": "435805", "author": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "body": "Joren -- I think that Joshua was just providing this as another option that you could use until a better option is available. I'm in the same situation as you; this non-scaled splash screen won't help us with our splash.\r\n\r\nI did not take Joshua's post to mean that they weren't going to work on other approaches. In fact, I'm encouraged by the fact that this is marked for 7.1.1.", "updateAuthor": { "name": "jpriebe", "key": "jpriebe", "displayName": "Jason Priebe", "active": true, "timeZone": "America/New_York" }, "created": "2018-03-21T16:24:31.000+0000", "updated": "2018-03-21T16:24:31.000+0000" }, { "id": "435811", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Right. I don't mind offering a crop zoom feature. I'm not saying no to the idea.\r\n\r\nWhat I'm posting above is an alternative solution for those who are interested. We already offer the ability to override the splash screen \"drawable\". And it's a commonly approach used by native Android developers. It also displays a splash screen like how it's done in WinRT universal apps too (doesn't scale the image at all and back-fills the surrounding area). Also, in the past, it was common to tile the image on Android instead of loading one large splash screen image since worst case scenario the app may be limited to a max heap size of 24 MB (avoids out-of-memory exceptions on low-end devices). The drawable-list approach has its merits.\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-21T20:15:27.000+0000", "updated": "2018-03-21T20:15:27.000+0000" }, { "id": "435880", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Bad news. I've spent a few days beating my head on this and have concluded that a cropped splash screen is *impossible* on OS versions older than Android 7.0.\r\n\r\nCropping the splash via an ImageView is not an option because by that point it's already too late. It can take 1-2 seconds on a fast device before the 1st activity's {{onCreate()}} gets called via a cold app start, which is our first chance to load any views. On a low-end Android 4.1 device I have, it can take several seconds (worst-case ~10 seconds like [~jpriebe] has said) before the {{Activity.onCreate()}} gets called, which can be made even worse if the app is multidexed (we can't optimize the multidex file loading; that's done by Google). But that said, by the time Titanium's 1st Activity gets created, we're already loading your main JavaScript which has the ability to display UI. So, it's simply too late at this point.\r\n\r\nThe \"android:windowBackground\" XML theme setting is the only viable option. Android loads this drawable on startup before Titanium's {{Application}} derived class gets created, which is why the splash appears so fast. Unfortunately, there's no hacks we can do to override how it's loaded (believe me, I tried). So, using Google's {{Drawable}} derived classes via the XML file as I've shown above is the only good solution and unfortunately none of Google's {{Drawable}} classes providing cropping support.\r\n\r\nOne interesting thing to note is that Android 7.0 and above offers the ability to load custom Drawable classes from XML. We can create our own Drawable that does cropping (I've written one in about 1 hour), but such a feature would be limited to Android 7.0 and higher. Doesn't do us any good for older OS versions. Google documents this under the \"Custom drawable\" section here...\r\nhttps://developer.android.com/reference/android/graphics/drawable/Drawable.html\r\n\r\nOn Android 8.0, Google offers the ability to load an XML layout on app startup via the \"android:windowSplashscreenContent\" XML theme setting. Google loads this layout before our Java {{Application}} derived class gets created. So, this is their official splash screen support, but it doesn't do us any good on older Android OS versions either.\r\nhttps://developer.android.com/reference/android/R.styleable.html#Window_windowSplashscreenContent\r\n\r\nSo, we have to conclude that this is a limitation on Google's end on devices older than Android 7.0. I just don't see any way to do it.\r\n\r\nNow, the \"drawable-list\" example I wrote up above is a pretty powerful solution. You can stack several drawables on top. Meaning you can display multiple images, shapes, fill colors, etc. And you have the ability to tile an image to fill the screen. There is a {{}} drawable too which lets you scale up a {{}}, but unfortunately there is no way to perfectly scale the image to just-fit the screen via XML. That can only be done programmatically but the {{windowBackground}} splash is loaded by Android before any Java code gets executed on our end. Everything must be done in XML.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-24T04:37:49.000+0000", "updated": "2018-03-24T04:37:49.000+0000" }, { "id": "435894", "author": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "body": "How about letting us change the contentView of the current splash screen instead of Titanium's activity containing a background image?\r\n\r\nI'm getting a bit tired of the discussion if it's possible or not on Android as I've created a *native app* in the past in which I have a cropped splash screen. Just sayin'... So it is possible.\r\n\r\nhttps://github.com/appcelerator/titanium_mobile/blob/master/android/titanium/src/java/org/appcelerator/titanium/TiRootActivity.java\r\n\r\nIn this file, lines 186-192 tell me that the background image is set as the background of the window. So, there is a window created somewhere in the code. It must be possible to give us the option do define the contentView of that window?\r\n", "updateAuthor": { "name": "jvos", "key": "jvos", "displayName": "Joren Vos", "active": true, "timeZone": "Europe/Brussels" }, "created": "2018-03-25T09:50:57.000+0000", "updated": "2018-03-25T10:00:55.000+0000" }, { "id": "435931", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~jvos], I don't think you understand how this works on Android. Titanium is not loading the splash screen image. The Android OS is. It works like the \"default.png\" on iOS. How it works is that the Android OS displays a launch window using the app's \"windowBackground\" drawable *+before+* the application code is loaded. Meaning it's not our activity window. We can't set its content except on Android 8.0 and higher. We can only tell the Android OS what drawable we want to display via pure XML only. This is an optimization Google has made. By the time the Android OS does create the app's launcher activity, it'll swap in the {{Window}} and {{DecoreView}} it has already created before loading the app.\r\nhttps://developer.android.com/topic/performance/launch-time.html\r\n\r\nAnd yes, we can display a cropped image in the {{TiRootActivity}} as you've noted. In fact, I did exactly that just last week (I've done it before too). But the problem is that it displays the image too late. The {{TiRootActivity.onCreate()}} method doesn't get called until 1-10 seconds after a cold app startup depending on the speed of the device. Worst-case, on a low-end Android 4.1 device with multidexing enabled, you'll see the system's default dark gray gradient background on startup for about 10 seconds until the {{TiRootActivity.onCreate()}} has a chance to load the splash image. That's the problem. And the response from people on this ticket have stated that this would be unacceptable. Versus the \"windowBackground\" technique we're currently using loads the image instantly on a cold start, even on the slow low-end device.\r\n\r\nAlso, the {{onConfigurationChanged()}} lines 186-192 you've noted does not load the image on startup. It reloads the background upon orientation change to grab a portrait/landscape image. If you comment out that code, you'll notice that the \"windowBackground\" splash image is still loaded on startup. This is because we're not loading it. The Android OS is.\r\n\r\nHere's the thing. By the time the {{TiRootActivity}} gets loaded, Titanium will load your main JavaScript. So, by that point, you can display a cropped image yourself via JavaScript. The amount of time between the {{TiRootActivity.onCreate()}} and the launch of your main JavaScript file is about 20-200 milliseconds on a cold start. It was 200 ms on my low-end Android 4.1 device that took about 10 seconds to call the Activity onCreate() method. So, this amount of time is negligible compared to the app load overhead that occurs before the activity gets created. My point being is if you're dead set in displaying an image via an Activity layout instead of Google's optimized \"windowBackground\", you can already do this today... but you'll have to live with that dark gradient background on startup until the activity window gets loaded.\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-03-26T18:57:18.000+0000", "updated": "2018-03-26T18:57:18.000+0000" }, { "id": "448947", "author": { "name": "dxgx82", "key": "dxgx82", "displayName": "Darius G", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Is any kind of progress on this topic? ", "updateAuthor": { "name": "dxgx82", "key": "dxgx82", "displayName": "Darius G", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-06-09T13:24:43.000+0000", "updated": "2019-06-09T13:24:43.000+0000" }, { "id": "448961", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~dxgx82], the best solution is to use a 9-patch PNG for your splash.\r\nhttps://developer.android.com/studio/write/draw9patch\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-06-10T18:38:22.000+0000", "updated": "2019-06-10T18:38:22.000+0000" }, { "id": "449080", "author": { "name": "dxgx82", "key": "dxgx82", "displayName": "Darius G", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks, Joshua. But problem is that i already using 9patch image from start. Android < 8 is looking OK but Android 8, 9 is streched... ", "updateAuthor": { "name": "dxgx82", "key": "dxgx82", "displayName": "Darius G", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-06-14T04:52:05.000+0000", "updated": "2019-06-14T04:52:05.000+0000" }, { "id": "449086", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~dxgx82], with a 9-patch PNG, you can control which parts of the image is stretched and which parts are not. The most common way of making a splash on Android is to have a centered image and then stretch a solid background color around it. What you can't really do on Android is use photos for a splash since their is no native support to letterbox or crop the splash image on the Android OS' end.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-06-14T17:30:57.000+0000", "updated": "2019-06-14T17:30:57.000+0000" } ], "maxResults": 32, "total": 32, "startAt": 0 } } }