My Code:
public class location
{
private class MyPhoneStateListener extends PhoneStateListener
{
//Get the Signal strength from the provider, each time there is an update
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength)
{
}
/*some text*/
}
how can i invoke "onSignalStrengthsChanged" method from "location" class.
You need to create a new MyPhoneStateListener instance and invoke the method on this instance.
For example:
public class location {
private class MyPhoneStateListener extends PhoneStateListener {
//Get the Signal strength from the provider, each time there is an update
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength)
{
}
/*some text*/
}
public void doSomething() {
PhoneStateListener listener = new MyPhoneStateListener();
listener.onSignalStrenghtsChanged(...);
}
}
Please notice that you can only create a MyPhoneStateListener instance in the location class because you defined the class private.
Also, notice that doSomething() belongs to location.
Related
I'm trying to implement abstract fragment with typed callback to use it in several subclasses.
How can I check if Context is instance of appropriate class?
My code of abstact CallbackFragment:
public abstract class CallbackFragment<C> extends Fragment {
protected C mCallback;
public CallbackFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
//just in case
if(context == null)
throw new NullPointerException();
try {
mCallback = (C) context; //this line not seems to throw any exception
} catch (ClassCastException exception) {
throw new RuntimeException(context.toString() + " must implement Callbacks");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
}
Vehicle list fragment:
public abstract class VehicleListFragment<T extends Vehicle>
extends CallbackFragment<VehicleListFragment.Callback<T>> {
//callback for any list of any vehicle
public interface Callback<T extends Vehicle> {
void onListItemSelected(T selectedItem);
}
//common code for list of any vehicle
public VehicleListFragment() {
}
}
Bus, Truck, Boat, Bike, whatever list fragment:
public class BusListFragment
extends VehicleListFragment<Bus> {
//code specific for list of bus
public BusListFragment() {
}
}
Vehicle details fragment:
public abstract class VehicleDetailsFragment<T extends Vehicle, C extends VehicleDetailsFragment.Callback<T>>
extends CallbackFragment<C> {
//common methods of callback for any vehicle
public interface Callback<T> {
void onVehicleEdited(T editeItem);
}
//common code for any vehicle
public VehicleDetailsFragment() {
}
}
Bus, Truck, Boat, Bike, whatever details fragment:
public class BusDetailsFragment
extends VehicleDetailsFragment<Bus, BusDetailsFragment.Callback> {
//specific for Bus methods
public interface Callback
extends VehicleDetailsFragment.Callback<Bus> {
void onSomethingSpecificForBusHappened(Bus bus);
}
//code specific for Bus
public BusDetailsFragment() {
}
}
I've tried to add an abstract method for CallbackFragment to get callback class:
public abstract class CallbackFragment<C> extends Fragment {
...
#NonNull
protected abstract Class<C> getCallbackClass();
#Override
public void onAttach(Context context) {
super.onAttach(context);
...
//now checking instanceof like this
if(!getCallbackClass().isAssignableFrom(context.getClass())){
throw new RuntimeException(context.toString() + " must implement Callbacks");
}
}
}
With BusDetailsFragment everything looks OK:
public class BusDetailsFragment
extends VehicleDetailsFragment<Bus, BusDetailsFragment.Callback> {
#NonNull
#Override
protected Class<Callback> getCallbackClass() {
return Callback.class;
}
...
}
But not with BusListFragment:
public class BusListFragment
extends VehicleListFragment<Bus> {
#NonNull
#Override
protected Class<Callback<Bus>> getCallbackClass() {
/**
* I'm not seeing any option here
*
* mCallback - is null yet. So, there is no way to use mCallback.getClass()
*
* Callback<Bus>.class - Cannot select from parameterized type
*/
//return mCallback.getClass();
//return Callback<Bus>.class;
}
...
}
Of course, I could create an own interface for every subclass of VehicleListFragment that extends VehicleListFragment.Callback (like in subclasses of VehicleDetailsFragment) but it will always look like this:
public interface Callback
extends VehicleListFragment.Callback<Bus> {
//nothing more here
}
This doesn't look like the best option for me. Maybe there is any other solution? Please share your thoughts. ANY help would be appreciated.
mCallback = (C) context; //this line not seems to throw any exception
this call will never throw an Exception. During Runtime, your C is replaced with Object(that's called Type-Erasure) - and everything is an Object. Therefore you can assign anything at this point.
To have the exception (or at least error-determination) at the point, where you need it, you can use:
public abstract class CallbackFragment<C> extends Fragment {
protected C mCallback;
protected Class<C> callbackClass;
public CallbackFragment(Class<C> clazz) {
this.callbackClass = clazz;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
//just in case
if(context == null)
throw new NullPointerException();
if (clazz.isAssignableFrom(context.getClass()){
mCallback = (C) context;
}else{
//oops
}
}
}
ofc. then your FragmentCreation would change from
CallbackFragment<Something> fragment = new CallbackFragment<Something>();
to
CallbackFragment<Something> fragment = new CallbackFragment<Something>(Something.class);
It's a little different, but allows you to keep track of the actual type at any time, bypassing the Type-Erasure.
ps.: For Inherited classes, you can do it more generic:
public abstract class CallbackFragment<C> extends Fragment {
protected Class<C> callbackClass;
public CallbackFragment() {
this.callbackClass = (Class<C>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];;
}
}
public class CallbackFragmentOfSomething extends <CallbackFragment<Something>>{
}
This only fails, if your actual class is not defined due to inheritance, but "on the fly":
CallbackFragment<Something> fragment = new CallbackFragment<Something>();
(Everything untested / no copy paste, but should be somewhat accurate)
Suppose I have defined a class with interface like this:
public class myClass {
public void test() {
//here I want to trigger `onStartListener`
}
interface OnStartListener {
public void onStart();
}
}
and class B I have defined like this:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass();
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
How can I trigger OnStartListener from test method of myClass so ClassB can handle it?
Yes, you need to subscribe your listener and call the method in the class A:
public class ClassB implements myClass.OnStartListener {
public void ClassB() {
myClass test1 = new myClass(this);
//test1.setListener(this);
myClass.test();
}
#Override
public void onStart() {
System.out.println("start triggered");
}
}
and
public class myClass {
OnStartListener myListener;
public myClass(OnStartListener myListener) {
this.myListener = myListener;
}
public void test() {
//here I want to trigger `onStartListener`
myListener.onStart();
}
interface OnStartListener {
public void onStart();
}
}
Have a look at how frameworks like swing handle listeners. Basically you need to "register" the listener instance (ClassB instance) with myClass and call onStart() on it.
ClassB would probably contain a List<OnStartListener> which is used in a loop and onStart() is called on each element. Registering would mean assing the instance of ClassB to that list.
I have the following:
public class Notifier{
CustomPlayer mCustomPlayer;
CurrentPlayer mCurrentPlayer;
}
public class MainActivity extends Activity{
public void onCreate(){
Notifier ntf = new Notifier();
if( index == 0){
ntf.mCustomPlayer = new CustomPlayer(this);
}
else{
ntf.mCustomPlayer = new CurrentPlayer(this); // having problem here
}
}
}
In Notifier class, I just want to have one object mCustomPlayer to switch between CustomPlayer and CurrentPlayer in MainActivity class.
I tried adding the following in Notifier class,
public class Notifier{
CustomPlayer mCustomPlayer;
CurrentPlayer mCurrentPlayer;
public Object getType(int index) {
if (index == 1) {
return CurrentPlayer.class;
}
else {
return CustomPlayer.class;
}
}
}
With that I am having a problem when trying to initialize mCustomPlayer in MainActivity class.
ntf.mCustomPlayer = new (ntf.mCustomPlayer)getType(0); // compile error
Is there a way to realize this?
It has been a day since I am trying to configure out the correct implementation.
Should I use Interface in this case?
To use the new keyword you must supply a class (i.e. new MyClass()).
You could use reflection for this... but wouldn't it be much simpler to just have a common superclass (or interface) for CustomPlayer and CurrentPlayer?
For example, suppose both CustomPlayer and CurrentPlayer have the playOne() and playTwo() methods. You could then define:
public interface Player {
void playOne();
void playTwo();
}
public class CurrentPlayer implements Player {
#Override
public void playOne() {
// code
}
#Override
public void playTwo() {
// code
}
}
private class CustomPlayer implements Player {
#Override
public void playOne() {
// code
}
#Override
public void playTwo() {
// code
}
}
public class Notifier {
Player mPlayer;
}
And then assign mPlayer with new CurrentPlayer() or new CustomPlayer() You can then call any methods on the interface.
You could using Reflection:
public class Notifier{
public CommonInterface getInstance(int index, Class<Activity> activity){
Class<?> claz = getType(0);
Constructor<?> cons = claz.getConstructor(activity);
return (CommonInterface) cons.newInstance(this);
//or you could just type cast it manually if you do not wish to use CommonInterface
}
But having a common interface is the right way to go. You dont have to worry about reflection then.
Since you have same function for both the classes so use interface and access the object -
public class MainActivity extends Activity{
interface CurrentPlayer { void game(); }
interface CustomPlayer { void game(); }
interface Player extends CurrentPlayer, CustomPlayer { }
public void onCreate(){
Player swan = new Player() {
#Override
public void game() {
System.out.println("Swan Player"); //Swan Player
}
};
}
}
Assume the following two classes:
public class Network {
private static Network instance;
public Network() {
instance = this;
}
public static Network getInstance() {
return instance;
}
public interface Listener {
public void event(String msg);
};
ArrayList<Listener> listeners = new ArrayList<Listener>();
public void addListener(Listener listener) {
listeners.add(listener);
}
}
public class Act1 extends Activity implements Network.Listener {
#Override
public void onCreate(Bundle b) {
Network.getInstance().addListener(this);
}
public void event(String msg) {
// do nothing
}
}
public class Act2 extends Activity implements Network.Listener {
#Override
public void onCreate(Bundle b) {
Network.getInstance().addListener(new Network.Listener() {
public void event(String msg) {
// do nothing
}
);
}
public void event(String msg) {
}
}
Will either of the Activities leak once a user moves on to another Activity? Will either Activity be prevented from getting GCed? Are there any problems with the Listener implementation above?
Your example has some mistakes.
For example you never instantiate Network and every time you instantiate it, the static field will reference another instance. A more proper way to write Network would be the following
public class Network {
private static final Network INSTANCE = new Network();
private Network() {/*empty*/}
public static Network get() {
return INSTANCE;
}
//rest of the code ommitted
}
However, if you are not removing the Activity instances from the Network singleton (that static field instance in the Network class - assuming you initialize it at some point), then that instance will always have a reference to your Activity objects that were added to it's ArrayList. This way they cannot be garbage collected.
how can I trigger AsyncTasks that are contained in another activity from my main activity?
public class DatabaseActivity extends Activity {
private class DbReader extends AsyncTask<..> {
#Override
protected List<MyData> doInBackground(..) {
//execute query etc
}
}
private class DbSaver extends AsyncTask<..> {
#Override
protected void doInBackground(MyData data) {
//save to dn
}
}
private class DbRemover extends AsyncTask<..> {
#Override
protected void doInBackground(MyData data) {
//remove in db
}
}
}
How can I trigger from MyApplication extends Actitivy?
i think you should use seperate class where AsyncTask is alone.
when your app needs more than one AsyncTask then you should use seperate AsyncTask and call it.
private class CommonTask extends AsyncTask<..> {
public CommonTask(Foo foo){
}
#Override
protected void doInBackground(MyData data) {
//remove in db
}
}
No you can pass diffrent value for constructor and check what you want from Activity either data save or remove or anything else...