Disclaimer: I'm coming from Swift so my idea on how delegation works is biased.
I have an interface defined:
public interface IChatButtonResponse {
void chat(ListingEntry listingEntry, String initialUserText);
}
My class has a local reference to it that is saved when instantiated:
public class ListingAdapter extends BaseAdapter {
private IChatButtonResponse delegate;
public ListingAdapter(Context context, ArrayList<ListingEntry> listingEntries, IChatButtonResponse delegate) {
this.delegate = delegate;
When I try to call the delegate in response to a button tap, I get a compilation error:
chatButton.setOnClickListener(new View.OnClickListener() {
delegate.chat(listingEntry, null); // Cannot resolve symbol 'chat'
});
Why can it not be resolved? I tried to make the method declaration in the interface public but that didn't change anything. (I would have been surprised if it did)
EDIT:
My usage of the interface in the same package:
public class MainActivity extends AppCompatActivity implements IChatButtonResponse {
.
.
.
#Override
void chat(ListingEntry listingEntry, String initialUserText) {
}
I am getting a compilation error here: 'chat(ListingEntry, String)' in ...sample.app.MainActivity' clashes with 'chat(ListingEntry, String) in ...sample.app.IChatButtonResponse'; attempting to assign weaker access privileges ('package-private'); was 'public'
Tried making the implementation method public with no change.
For the original error in question, the clue was found on another error I hadn't noticed earlier on the chatButton.setOnClickListener.
The OnClickListener method onClick must be overridden like this:
chatButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String referenceID = listingEntry.referenceID;
delegate.chat(listingEntry,null);
}
});
This fixes the resolution error at the call site.
Related
I am working on an Android app and I came across the following code for a set of Callbacks from C++.
I am wondering why, using an instance of the interface class JNIListener instead of implementing the interface and adding the Callbacks directly, makes sense.
public interface JNIListener {
void onProcessingStarted();
void onResultAvailable();
}
public class MainFragment extends Fragment {
......
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
.....
mListener = new JNIListener() {
#Override
public void onProcessingStarted() {
NavDirections action = MainFragmentDirections.actionMainFragmentToResultFragment();
NavHostFragment.findNavController(ThisFragment).navigate(action);
}
#Override
public void onResultAvailable(){
....
}
}
subscribeListener(mListener);
}
}
instead of :
public class MainFragment extends Fragment implements JNIListener{
......
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
.....
subscribeListener(this);
}
#Override
public void onProcessingStarted() {
NavDirections action = MainFragmentDirections.actionMainFragmentToResultFragment();
NavHostFragment.findNavController(thisFragment).navigate(action);
}
#Override
public void onResultAvailable(){
....
}
}
I don't get the advantages of the first approach.
The second makes more sense to me: The callbacks have complete access to the members of the MainFragment.
The first approach should have its pro, otherwise why would someone have done it that way.
The person who wrote that code is for sure more experienced than I am. If I am doing something weird by preferring the second approach, it would be nice to understand why it is weird, learn something and avoid the issue next time.
The only advantage for the first approach is If you need two or more interfaces for separate things in your class. In every other case, I would use the second approach since it makes the code looks cleaner.
I created an App, where I get answers from my Server to my HelperClass. The HelperClass has several #override Methods. This I override this Methods in every activity different.
So now my Problem is, I get lots of Problems, casue of multi threading. For example with a simple Toast. I have to use runOnUiThread() every time. Or "Only the original thread that created a view hierarchy can touch its views." when a overridden Helperclass method should use a (for example) MainActivity-Method to set a new layout.
Is there any solution, how I can solve those problems?
Code example:
public abstract class HelperClass extends AppCompatActivity{
#Override
public void methodOne() { }
#Override
public void methodTwo() { }
}
Here are my Methods defined. An another Class gets the answer from the Server and call them. (everything works).
I override them in every Activity (here for example MainActivity)
public class MainActivity extends HelperClass {
#Override
protected void onCreate(Bundle savedInstanceState){
setContentView(R.layout.first_layout);
}
#Override
public void methodOne() {
Toast.makeText(this,"text",Toast.LENGTH_SHORT).show();
}
#Override
public void methodTwo() {
setContentView(R.layout.second_layout);
}
}
So I will get Error, when I use them without runUIThread(). I need a solution for everywhere, cause I think this is not clean. There should be a better way then using runUIthread() in every single method, when I want to use a View or something else (till now I only had this two Problems, there are still 20-30 Funktions to declare).
I often have to deal with this kind an error when programming in Java on Android.
For example I have a class where I set a flag.
public class ViewActivity extends Activity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
...
}
In another class I want to reset the FLAG_KEEP_SCREEN_ON
class DrawOnTop extends View {
...
if (condition) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
but this doesn't work, since I get "The method getWindow is undefined for the type DrawOnTop".
So I try to define a clearFlags method in ViewActivity class
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and to call it from the DrawOnTop class:
if (condition) {
ViewActivity.clearFlags();
}
This doesn't work as well: I get "Cannot make a static reference to the non-static method clearFlags() from the type ViewActivity".
Well, let's make it static then.
static void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and then I get "Cannot make a static reference to the non-static method getWindow from the type Activity"
How could I execute such a statement?
If your DrawOnTop class is nested within the ViewActivity you can create a local Context variable and use it to call the getWindow(). If that's not the case then create a receiver in your activity class then from DawOnTop send an intent with your trigger to do whatever the job is. Do not instantiate your activity class, bad idea!
You can send getWindow() as parameter into clearFlags method.
Call clearFlags(Window window) from your activity: WindowHelper.getInstance().clearFlags(getWindow());
Helper class:
public class WindowHelper {
public static final WindowHelper instance = new WindowHelper();
public static WindowHelper getInstance() {
return instance;
}
public void clearFlags(Window window) {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
I tried to implement the solutions suggested by Aksaçlı and this turned out to be very simple:
In the ViewActivity class DrawonTop is called this way:
mDrawOnTop = new DrawOnTop(this);
The constructor of the second class contains this:
public DrawOnTop(Context context) {
super(context);
Therefore ViewActivity.clearFlags(); has simply to be rewritten as ((ViewActivity)getContext()).clearFlags();
Perhaps you should refer to an initialised object in your static method. So instead of:
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
you should create a static instance variable of your window:
private static staticWindowInstance;
void clearFlags() {
getStaticWindowInstance().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
For more information, you should check out the Singleton design pattern.
I have a BaseActivity like bellow... Where My Interface global object on super class beame null.
public abstract class BaseActivity extends BaseTabActivity {
//did some implementation
}
public abstract class BaseTabActivity extends BasePickerActivity {
//did some implementation
}
public abstract class BasePickerActivity extends Activity {
// This is an interface
private IOnImagSelected iOnImagSelected;
public void imagePicker(IOnImagSelected iOnImagSelected){
this.iOnImagSelected = iOnImagSelected;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// process data and called iOnImagSelected
// Here I get null point which mean iOnImagSelected is null
iOnImagSelected.onImageSelected(imagepath)
}
}
Now I have a Activity like
public class MyActivity extends BaseActivity implements IOnImagSelected {
public void onPickImageClick(View v){
imagePicker(this);
}
#Override
poublic void onImageSelected(){
}
}
Why My interface variable became null . Please help me with this
I solved it its all hapening because of this option on my Google Nexus 7 developer settings
goto settings->Developer options
in that in APPS category(scroll down to see), see the option
Don't keep Activities (Destroy every Activity as soon as user leabes it).
I found this from this post
That to that guy.:)
You're passing one Activity, MainActivity to the BasePickerActivity but when BasePickerActivity is active MainActivity is null. Basically, your code is invalid; you ought to use Fragments for this sort of thing.
This seems like an elementary problem so I'm sure it's something small I've overlooked. Maybe I've just been looking at it too long.
I've been trying to create an onClick Listener in a view, and I have a public set method to set the listener. But when I try to call that method outside of the class I get an error saying it can't resolve the method.
I've tried creating other public methods or public member variables but I can't view any of them outside of the class for some reason.
Here is some relative snippets:
PaintView: (The class I can't get public members from)
public class PaintView extends View {
public interface OnPaintClickedListener
{
public void onPaintClicked(int color);
}
private OnPaintClickedListener _onPaintClickedListener;
public void setOnPaintClickedListener(OnPaintClickedListener listener)
{
_onPaintClickedListener = listener;
}
...
}
PaletteView: (The class that uses a PaintView)
public class PaletteView extends ViewGroup {
....
public void addColor(Context context, int color)
{
View newPaintView = new PaintView(context, color);
//setOnPaintClickedListener gives the message "Cannot resolve method setOn...blah blah'
newPaintView.setOnPaintClickedListener(new PaintView.OnPaintClickedListener()
{
#Override
public void onPaintClicked(int color)
{
}
});
this.addView(newPaintView);
}
}
It does ok with the interface code, but it just can find that setOnPaintClickedListener method.
Thanks in advance, I'm 97% sure I'm going to feel like an idiot as soon as somebody points out my mistake.
Change to:
PaintView newPaintView = new PaintView(context, color);
explanation...as the variable you were using was declared with type View, the compiler wasn't able to find the method that was defined in the subclass PaintView, so it complains.
Alternatively, you could leave the same declaration and when calling the specific method, you would have to do cast to the subclass like this:
((PaintView)newPaintView).setOnPaintClickedListener