I am implementing a splash screen that is visible until the main Activity of my app manages to render a PDF. When I am opening the app, by clicking on the launcher icon, I can see the splash screen normally.
When I try to open a PDF with the app, there is a delay until MainActivity
's onCreate()
completes, and then MainActivity
is displayed directly (without presenting the splash image first). However, I have noticed that the SplashActivity
's onCreate()
method is executed.
My code so far:
The Splash Activity:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Uri uri = intent.getData();
Intent intentForActivity = new Intent(this, MainActivity.class);
if (uri != null)
intentForActivity.putExtra("URI", uri.toString());
startActivity(intentForActivity);
finish();
}
}
The Activity that I am waiting for (MainActivity
):
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
// some dummy delay for this example, so that the Splash Screen
// is displayed until this Activity is ready
// (this is NOT the actual code of my application!)
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The relevant part of the Manifest file:
<activity
android:name=".SplashActivity"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/pdf" />
<data android:pathPattern="*\\.pdf" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:theme="@style/AppTheme.NoActionBar" />
The problem seems to be in the intent-filter
for handling PDF files, but I cannot figure what is wrong and why.
UPDATE: Adding android:launchMode="singleInstance"
in the configuration of SplashActivity
in the Manifest solves the issue, but creates many other issues for me.
I managed to solve the issue by doing the following:
As David Wasser correctly mentioned, this occurs when my app is launched in the task of the app that launches it (i.e., when I open a PDF from within a file manager).
To solve this, in the Manifest
, I added this to the configuration of the SplashActivity
: android:launchMode="singleTask"
.
Then, I noticed that this way, multiple instances of the MainActivity
would initiate. Hitting the back button would navigate me between them. To solve this, in the SplashActivity
class, before I called startActivity()
I added: intentForActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
(documentation: FLAG_ACTIVITY_CLEAR_TASK).
A problem that I noticed is that the onDestroy()
method of the old MainActivity
sometimes executes after the onCreate()
of the new one. So, you should be careful when and what you modify/create/delete/etc in your onDestroy()
method.
There might be better ways to achieve this result, but this worked well for me.
My updated relevant part of the Manifest
:
<activity
android:name=".SplashActivity"
android:launchMode="singleTask"
android:theme="@style/SplashTheme">
My updated SplashActivity
:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
final Uri uri = intent.getData();
Intent intentForActivity = new Intent(this, MainActivity.class);
if (uri != null)
intentForActivity.putExtra("URI", uri.toString());
intentForActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intentForActivity);
this.finish();
}
}