I have a video player app where I need to access the lifecycle of an abstract activity from another class in Android. In my abstract activity, I've tried using LifecycleRegistry, but this is getting me the lifecycle owner not the actually lifecycle of the abstract class. How can I access the lifecycle of an abstract activity from another class?
Here is my abstract activity:
abstract public class MainActivity extends AppCompatActivity {
private LifecycleRegistry lifecycleRegistry;
VideoPlayer videoPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleRegistry = new LifecycleRegistry(this);
lifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
setContentView(R.layout.activity_main);
videoPlayer = new VideoPlayer();
playVideo();
}
public void playVideo(){
videoPlayer.init();
//calls function in VideoPlayer class
}
#Override
protected void onResume() {
super.onResume();
lifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);
}
#Override
protected void onDestroy() {
super.onDestroy();
lifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
}
}
Here is the class where I need to get the lifecycle of my abstract MainActivity:
public class VideoPlayer {
public void init() {
playVideo();
}
public void playVideo() {
//async call happens here, I need getLifeCycle() from MainActivity
}
}
Don't know a know about the context of you feature, but you You can do smth
public class VideoPlayer {
private Lifecycle mLifecycle;
public VideoPlayer(Lifecycle lifecycle) {
mLifecycle = lifecycle;
}
public void init() {
playVideo();
}
public void playVideo() {
//you have mLifecycle now
}
}
In Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
videoPlayer = new VideoPlayer(getLifecycle());
}
Related
I have an Activity which creates a class that does some work. What is the typical Android method of having this class report back to the Activity in order to update the UI?
My activity, which creates the class:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass obj = new MyClass(this);
obj.DoWork();
}
}
The class that does the work, and wants to report back some
public class MyClass(Context context) {
private Context context;
public void DoWork() {
//Do some work with a countdown timer
//Report back some values
}
}
You can create your own interface like this:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyClass obj = new MyClass(this);
obj.setOnWorkDoneListener(new MyClass.OnWorkDoneListener(){
#Override
public void onDone(Values values) {
//Work done, use values
updateUI(values);
}
});
obj.DoWork();
}
}
public class MyClass(Context context) {
private Context context;
public interface OnWorkDoneListener{
void onDone(Values values);
}
private OnWorkDoneListener listener;
public void setOnWorkDoneListener(OnWorkDoneListener listener){
this.listener = listener;
}
public void DoWork() {
//Do some work with a countdown timer
when(workEnded) listener.onDone(backValues);
}
}
I am trying to understand better how to create a custom listener with a simple example but I don't know how to start the interface so that it is not null:
public class MainActivity extends AppCompatActivity implements ListenerButton{
TextView helloToOther;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
helloToOther = findViewById(R.id.helloWorldToOtherActivity);
helloToOther.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, ButtonActivity.class));
}
});
}
#Override
public void onClickButton(View view) {
Toast.makeText(this, "Estoy en la primera activity", Toast.LENGTH_SHORT).show();
}
}
This is the second activity:
public class ButtonActivity extends AppCompatActivity {
Button btnInterface;
ListenerButton listenerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
btnInterface = findViewById(R.id.button_activity__btn__button_interface);
setUpButtonInterface();
}
private void setUpButtonInterface() {
btnInterface.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listenerButton.onClickButton(v);
}
});
}
}
And there's the interface:
public interface ListenerButton {
void onClickButton(View view);
}
Basically I get a null pointer exception on the second activity because the interface is null, but I don't fall right now as I can start it. Thank you very much.
the reason you are getting a null pointer exception is because you haven't assigned anything to variable listenerButton and therefor it is in fact null!!
you don't need a new interface for that you just need to do this:
public class ButtonActivity extends AppCompatActivity {
Button btnInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
btnInterface = findViewById(R.id.button_activity__btn__button_interface);
setUpButtonInterface();
}
private void setUpButtonInterface() {
btnInterface.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do whatever you want to do when button is clicked!
}
});
}
}
if you want to define whatever you want to do when button is clicked you need a class and not an interface:
public class ButtonListener implements View.OnClickListener{
#Override
public void onClick(View v) {
//do whatever you want to do when button is clicked!
}
}
and then in your activity do this:
public class ButtonActivity extends AppCompatActivity {
Button btnInterface;
ListenerButton listenerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button);
listenerButton = new ButtonListener();
btnInterface = findViewById(R.id.button_activity__btn__button_interface);
setUpButtonInterface();
}
private void setUpButtonInterface() {
btnInterface.setOnClickListener(listenerButton);
}
}
Create a new file:
MyListener.java:
public interface MyListener {
// you can define any parameter as per your requirement
public void callback(View view, String result);
}
In your activity, implement the interface:
MyActivity.java:
public class MyActivity extends Activity implements MyListener {
#override
public void onCreate(){
MyButton m = new MyButton(this);
}
// method is invoked when MyButton is clicked
#override
public void callback(View view, String result) {
// do your stuff here
}
}
In your custom class, invoke the interface when needed:
MyButton.java:
public class MyButton {
MyListener ml;
// constructor
MyButton(MyListener ml) {
//Setting the listener
this.ml = ml;
}
public void MyLogicToIntimateOthers() {
//Invoke the interface
ml.callback(this, "success");
}
}
I want to call method of Other activity. I searched alot and tried by myself but failed. It work when i call from class to class like classA m=new classA();
m.function();
But i want to call from another activity method. Please help
public void onNotificationPosted(StatusBarNotification sbn) {
ChatActivity ch=new ChatActivity();
ch.location();
}
public class ApplicationContext extends Application {
public ActivityMain activityMain;
public void setActivityMain(ActivityMain activityMain) {
this.activityMain = activityMain;
}
public ActivityMain getActivityMain() {
return activityMain;
}
In ActivityMain.class
public class ActivityMain extends BaseProject implements MainView {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ApplicationContext.getInstance().setActivityMain(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
ApplicationContext.getInstance().setActivityMain(null);
}
Use it anywhere like Activity, Fragments, Broadcast Receiver or Service like
if (ApplicationContext.getInstance().getActivityMain()!=null){
ApplicationContext.getInstance().getActivityMain().callAnyMethod();
}
Enjoy :)
I have a parent activity NavigationActivity and it does something like this:
public class NavigationActivity extends Activity {
protected LinearLayout navigationBar;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
navigationBar = findViewById(R.id.navbar);
}
}
It has one method that sets the visibility of navigationBar:
#Override
protected void setNavbarVisibility(int view) {
if (this.navigationBar != null) {
this.navigationBar.setVisibility(view);
}
}
I have an activity AdventureActivity that extends NavigationActivity:
public class AdventureActivity extends NavigationActivity {
EditText title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstancState);
renderAdventureLayout();
}
public void renderAdventureLayout() {
Handler h = new Handler();
title.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(final View v, boolean hasFocus) {
if (hasFocus) {
h.postDelayed(new Runnable() {
#Override
public void run() {
setNavbarVisibility(View.GONE);
}
}, 200);
} else {
h.postDelayed(new Runnable() {
#Override
public void run() {
setNavbarVisibility(View.VISIBLE);
}
}, 200);
}
}
}
}
}
Now, I didn't have to declare or initialize navigationBar in AdventureActivity, and it's already initially visible. However, the statement setNavbarVisibility(View.GONE); doesn't seem to work in AdventureActivity unless I also initialize navigationBar as it was initialized in NavigationActivity because according the debugger, navigationBar was null when it wasn't initialized in AdventureActivity. I find it redundant having to initialize navigationBar in both activities.
You haven't provided a content view in either of your activities, which results findViewById() method to return null.
If you want to create such an activity hierarchy, that means, that NavigationActivity should have an abstract method, that subclasses should implement:
public abstract class NavigationActivity extends Activity {
...
#LayoutRes
protected abstract int getLayoutId();
}
Then AdventureActivity would become:
public class AdventureActivity extends NavigationActivity {
...
#Override
#LayoutRes
protected int getLayoutId() {
return R.layout.some_activity;
}
}
Now in NavigationActivity#onCreate():
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutId());
navigationBar = findViewById(R.id.navbar);
}
This mandates each of subclasses to provide a layout, where exists a LinearLayout with id navbar, otherwise your navigationBar would end up being null.
I am developing an Android app and thus, I have a MainActivity class. Inside of that MainActivity class, I have a method, let's call it doSomething():
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void doSomething(){
// bla bla bla
}
}
I also have a different class (with different layout) that is called OtherActivity. I want to use the doSomething method inside it:
public class OtherActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
}
}
I tried this:
public class OtherActivity extends AppCompatActivity {
MainActivity main;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
MainActivity main = new MainActivity();
main.doSomething();
}
}
But it does not work. I also tried to make OtherActivity to extend the MainActivity, doing the following:
public class OtherActivity extends MainActivity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
// Let's use doSomething()
super.doSomething();
}
}
But it does not allow me to initialize the layout...
How can I do?
Thanks in advance.
To communicate between to Activity Broadcast is the best way, and for the same application, we can use local broadcast using LocalBroadcastManager.
First, we should register one broadcast in MainActivity,
public class MainActivity1 extends AppCompatActivity {
public static final String INTENT_FILTER = "do_some_action";
public static final String INTENT_BUNDLE_VALUE = "value1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
LocalBroadcastManager.getInstance(this).registerReceiver(
mChangeListener, new IntentFilter(INTENT_FILTER));
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mChangeListener);
}
private BroadcastReceiver mChangeListener = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intentData) {
// you can do anything here
if (intentData != null && intentData.hasExtra(INTENT_BUNDLE_VALUE)) {
String value = intentData.getStringExtra(INTENT_BUNDLE_VALUE);
doSomeAction(value);
}
}
};
private void doSomeAction(String value) {
}
}
Then to do some action in MainActivity from OtherActivity, we can send Local broadcast from OtherActivity it will reach the receiver of Which we register in MainActivity,
public class OtherActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
// You can call MainActivity to do some actions
Intent intent = new Intent(MainActivity1.INTENT_FILTER);
intent.putExtra(MainActivity1.INTENT_BUNDLE_VALUE, "Any string or any value");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Done!!!.
Something like this should do the trick, I'm going to make a static navigator to handle your navigation logic. If you are opposed to static methods you could also make them on your Application object to make it easier to manage dependencies, I'm just making it static for simplicity.
//Making this fully static for simplicity, this is fine for a small app
//you can make it a singleton on the application class for more flexibility
public class Navigator {
//static member vars that determine navigation
// pass in Context if needed for navigation purposes
public static void doSomething(Context context){
// bla bla bla
}
}
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
}
private void doSomething() {
Navigator.doSomething(this);
}
}
public class OtherActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other_activity_layout);
}
private void doSomething() {
Navigator.doSomething(this);
}
}