Reputation: 123
Hi I am trying to call this method in MainActivity from another class called Startup that extends Application so that it could load each time the app starts:
Can someone show me how to do this? I have read lots of answers but I have not seen any questions that has a class that extends Application yet, I think that caused the issue. All answers that I have seen are about how to call a method from another class that extends Activity :/
this is the method in mainActivity:
public void showPinLayout() {
//if initialize in oncreate will cause nullpointer error
indicatorDots = (IndicatorDots) findViewById(R.id.indicator_dotsMain);
pinLockView = (PinLockView) findViewById(R.id.pinlockviewMain);
pinLockView.attachIndicatorDots(indicatorDots);
...
}
this is the Startup class that extends Application and has been initialized in manifest:
<application
android:name=".Startup" ...>
public class Startup extends Application {
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Startup", Toast.LENGTH_SHORT).show();
MainActivity mainActivity = new MainActivity();
mainActivity.showPinLayout();
}
}
Upvotes: 0
Views: 455
Reputation: 5598
Since you cannot new
an activity and you should not hold a static reference to an activity to call this method on (since it can lead to leaks), the proper way to access an activity method through app class is through BroadcastReceiver
. Here is a simple example:
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final String ACTION_SHOW_PIN_LAYOUT = "com.example.package.SHOW_PIN_LAYOUT";
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
showPinLayout();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate();
...
registerReceiver(mReceiver, new IntentFilter(ACTION_SHOW_PIN_LAYOUT));
}
@Override
protected void onDestroy() {
super.onDestroy();
...
unregisterReceiver(mReceiver);
}
}
Startup.java
public class Startup extends Application {
...
public void callShowPinLayout() {
sendBroadcast(new Intent(MainActivity.ACTION_SHOW_PIN_LAYOUT));
}
}
Note that for this to work, MainActivity must be created first, so call callShowPinLayout
in a resonable time when you have ensured of your activity creation.
Also I'd suggest EventBus library which is created to ease out these kind of stuff.
Since you intend to show a pin lock when user starts the app, you should only deal with activities. I would recommend implementing something like the following: Declaring your pin lock layout as an independent activity. Creating a startup activity (could be a splash screen) and marking it as the launcher activity in AndroidManifest.xml
to decide whether to show the pin lock or main activity.
StartupActivity.java
public class StartupActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup);
boolean shouldShowLockScreen = true; // you can replace this with your own lock screen visibility algorithm
if (shouldShowLockScreen) {
// Open LockScreenActivity
Intent intent = new Intent(this, LockScreenActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else {
// Open MainActivity
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
finish();
}
}
AndroidManifest.java
<application
...>
<activity
android:name=".StartupActivity"
android:theme="@style/StartupTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
...
</activity>
</application>
With this implementation whenever user enters the app with a cold start, the lock screen algorithm determines if he/she should enter MainActivity
or not and if a hot start happens you can easily start your mighty StatupActivity
if needed to in onResume()
of your MainActivity
.
Upvotes: 1
Reputation: 11018
I would suggest doing something like let the MainActivity start, and in onCreate of the MainActivity call the method in Startup class to initialize some method. the reason is that you don't know at what time the activity will be initialized so wait for it then on Lifecycle Callback initialize some method if needed.
For ex.
public class Startup extends Application {
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Startup", Toast.LENGTH_SHORT).show();
}
public void initMain(Context context){
((MainActivity)context).showPinLayout();
}
}
and in MainActivity do something like this.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//just before showing the UI, call the application class method to initialize some method if needed
((Startup)getApplicationContext()).initMain(this);
}
Upvotes: 1