I'm doing some Android development and I have an object, which doing a specific task. When that task is done I need to inform my main method (Main Activity), which is constantly running, that the process has been finished and pass some information about it.
This may sound a bit unclear, so I'll give you an example:
Take a look at the setOnClickListener() method in Android:
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
//This method is called on click
#Override
public void onClick(View v) {
//The View is passed in an anonymous inner class
}
});
It waits for a button to be clicked and calls the onClick(View v) method. I am seeking to achieve the same code structure. How to do this?
You mentioned "process". If you are truly doing something in a different process, then you need to look at interprocess communications (IPC). Otherwise, you can use an interface:
Create a class called MyListener:
public interface MyListener {
void onComplete();
}
In your class that will notify your activity:
MyListener myListener;
public void setMyListener(MyListener myListener){
this.myListener = myListener;
}
Then, when you are ready to notify your main activity, call this line:
myListener.onComplete();
Last, in your MainActivity implement MyListener:
public class MyListener extends Activity implements MyListener {
///other stuff
#Override
public void onComplete(){
// here you are notified when onComplete it called
}
}
Hope this helps. Cheers.
This is exactly Listener pattern that you use with views in android. What you want to do is declare an interface in your class that's doing the job, and pass an instance of this interface. Raw example:
TaskDoer.java:
public class TaskDoer {
public interface OnTaskDoneListener {
void onDone(Data data);
}
public void doTask(OnTaskDoneListener listener) {
// do task...
listener.onDone(data);
}
}
Activity:
public void doTaskAndGetResult() {
new TaskDoer().doTask(new TaskDoer.OnTaskDoneListener() {
public void onDone(Data data) {
// do something
}
}
}
Related
I have been looking for my question on Google and inside the forum but I cannot an answer so far. I am using android studio to code an app in Java
The thing is : inside a class, I have overrided the OnClick() method because I have to implement a lot of views.
Now I want to call a function just before OnClick() is called.
What I mean is, for instance, if the user taps on a button, before OnClick() is called I want one of my methods to be called.
Does anyone know how to do this ?
Thank you in advance
I want to call a function just before OnClick() is called
You can use a logic inside onClick() like,
if(userhaspermission())//your method to check if the user has permission
{
//your onclick operation code
}
Make your checking permission method with return type as boolean
Implement your custom OnClickListener as follows
public abstract class MyOnClickListener implements OnClickListener {
#Override
public void onClick(View v) {
//Do common action
if(condidtionSatisfied){
performClick(v);
}
}
public abstract void performClick(View v);
}
Set onClickListener to any component as follows:
button.setOnClickListener(new MyOnClickListener() {
#Override
public void performClick(View v) {
//Execute post click action
}
});
This will ensure your common code will be called for all the views and it would be much cleaner approach.
Override the onClick() method and write your first logic which you want.
Write your own Listener like Sagar said
This logic is quite similar to Sagar's Answers.
Write abstract class as given below
public abstract class OnClick implements View.OnClickListener {
public void beforeClick(View v) {
}
#Override
public void onClick(View v) {
beforeClick(v);
performClick(v);
afterClick(v);
}
public void performClick(View v) {
}
public void afterClick(View v) {
}
}
NOTE : See in above code it implements View.OnClickListener, so this logic will works for views which extends View super class. If you want above logic for object's which needs Dialog interface onClick then you need to modify it for DialogInterface.OnClickListener.
So you can use above logic as below
//Let say you need it for button with id button
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClick() {
#Override
public void beforeClick(View v) {
Toast.makeText(MainActivity.this, "Before", Toast.LENGTH_SHORT).show();
}
#Override
public void performClick(View v) {
Toast.makeText(MainActivity.this, "Click", Toast.LENGTH_SHORT).show();
}
#Override
public void afterClick(View v) {
Toast.makeText(MainActivity.this, "After", Toast.LENGTH_SHORT).show();
}
});
I have trouble understanding this code. I get that findViewById will get the button widget and then it'll cast it. Then, it's going to use the button to call the setOnClickListener method. However, I don't know what is that argument being passed into the setOnClickListener and I have never seen code like that before. How is it that it creates a new object but is able to create a method of its own within another method's argument? Would be great if someone could explain that. Also, what type of object is the setOnClickListener method taking in?
btn = (Button)findViewById(R.id.firstButton);
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
tv.setText(months[rand.nextInt(12)]);
tv.setTextColor(Color.rgb(rand.nextInt(255)+1, rand.nextInt(255)+1, rand.nextInt(255)+1));
}
});
It works like this. View.OnClickListenere is defined -
public interface OnClickListener {
void onClick(View v);
}
As far as we know you cannot instantiate an object OnClickListener, as it doesn't have a method implemented. So there are two ways you can go by - you can implement this interface which will override onClick method like this:
public class MyListener implements View.OnClickListener {
#Override
public void onClick (View v) {
// your code here;
}
}
But it's tedious to do it each time as you want to set a click listener. So in order to avoid this you can provide the implementation for the method on spot, just like in an example you gave.
setOnClickListener takes View.OnClickListener as its parameter.
This is the best way to implement Onclicklistener for many buttons in a row
implement View.onclicklistener.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
This is a button in the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_submit = (Button) findViewById(R.id.submit);
bt_submit.setOnClickListener(this);
}
This is an override method
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.submit:
//action
break;
case R.id.secondbutton:
//action
break;
}
}
That what manual says about setOnClickListener method is:
public void setOnClickListener (View.OnClickListener l)
Added in API level 1 Register a callback to be invoked when this view
is clicked. If this view is not clickable, it becomes clickable.
Parameters
l View.OnClickListener: The callback that will run
And normally you have to use it like this
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
Take a look at this lesson as well Building a Simple Calculator using Android Studio.
its an implementation of anonymouse class object creation to give ease of writing less code and to save time
It works by same principle of anonymous inner class where we can instantiate an interface without actually defining a class :
Ref: https://www.geeksforgeeks.org/anonymous-inner-class-java/
I've recently got into Android and have been looking at examples about Inner classes but don't really understand what the use of them is. They are used often when making listeners and when making a full class is unnecessary right? Maybe someone can explain it to me in laymans terms, also what would the alternative to using an inner anonymous class in this situation be?
This code:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
Thanks
One alternative pattern is to make the container class itself a listener.
public class MyClass implements View.OnClickListener {
#Override
public void onClick(View v) {
// Do something when button is clicked
}
public void initOrSomething() {
button.setOnClickListener(this);
}
}
However you may run into trouble if you have more than one button that needs to behave differently.
Another way is to have different listener classes for each button
public class Button1Listener implements View.OnClickListener {
#Override
public void onClick(View v) {
// Do something when button1 is clicked
}
}
public class Button2Listener implements View.OnClickListener {
#Override
public void onClick(View v) {
// Do something when button2 is clicked
}
}
button1.setOnClickListener(new Button1Listener());
button2.setOnClickListener(new Button2Listener());
Anonymous inner classes are just a more compact representation of the second pattern.
EDIT: Variations of both patterns are possible, where contents of the View object are examined to determine which button was clicked or constructor arguments are passed to the listener class to change listener behavior etc.
They are used often when making listeners and when making a full class is unnecessary right?
Listeners in Android, or other interfaces in other situations. But in essence, that's about it.
what would the alternative to using an inner anonymous class in this situation be?
It would be to create a class which implements this interface and submit it as an argument. For instance:
public class MyListener
implements View.OnClickListener
{
// implement onClick(), etc etc
}
// In code:
button.setOnClickListener(new MyListener(...));
That's quite simple: What you are doing is just creating a class. For the JVM (or dalvik in this case), it doesn't matter if the class is it's own compilation unit (a file), an inner class or an anonymous class(*). So you have three equally valid options:
Option 1 Your example:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
Option 2 named inner class:
public MyActivity extends Activity {
static class MyListener implements View.OnClickListener {
#Override
public void onClick(View v) {
// do something
}
}
....
button.setOnClickListener(new MyListener());
}
and Option 3 Different Files:
File MyListener.java
public class MyListener implements View.OnClickListener {
#Override
public void onClick(View v) {
// do something
}
}
File MyActivity.java
import MyListener.java
public MyActivity extends Activity {
....
button.setOnClickListener(new MyListener());
}
Which of these options you use is completely subjective - Depending on your needs and usage, one or the other makes more sense.
However, generally in UI listeners, you don't want to have any logic that is disjunct from the logic of the Activity you are programming. Hence you use the anonymous class, because all the code stays in one place and makes it decently readable.
I have an Android application, where inside an onCreate() method of an Activity a button is defined to have an onClick method. In code:
public void onCreate(Bundle savedInstanceState) {
/.../
buttonSave = (Button) findViewById(R.id.store_button_save);
buttonSave.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
saveEditor(v);
}
});
/.../
}
My question is, how can I call this nested method onCLick() from an Android unit test? myActivity.onClick(myButton) does not work, since onClick() is not a method defined in the activity itself.
Btw, I should not be changing any original source code for my tests.
You can test this by not creating such an anoynmous class.
Instead create a normal inner class, and assign a new instance to to the listener:
public static class MyClickListener implements OnClickListener {
Editor editor;
public MyClickListener(Editor e) {
this editor= e;
}
public void onClick(View v) {
editor.saveEditor(v);
}
}
buttonSave.setOnClickListener(new MyClickListener());
In JuniTest
public void testOnClickListener() {
Editor e = new Editor();
MyClickListener l = new MyClickListener(e);
l.onClick();
// however you check for correct result
assertTrue(checkSaveEditor(e));
}
But why not just write unitest for method saveEditor() only?
This is sufficient, you can rely that onClick() works.
The onClick method is defined inside an anonymous class, so you cannot directly invoke it. Instead you need trigger the click event from the outer class. Don't know much about Android development but the following post explains how to test such as scenario using ActivityManager to simulate a button click with #UIthreadTest annotation. How to call Button.performClick in Android JUnit test case?
Is View.OnClickListener() a function or interface? When we try to set a onclicklistener() method in android, we use new View.OnClickListener() and it bugs me there cuz as far as I know,
we don't need to initialize an object of class containing static method inorder to use those methods. Why we do this?
When we use implements inorder to implement an interface, we don't call the static methods of the interface.
So can some one tell me why do we do:
new View.OnClickListener(), for using onclick() method?
Why do we use () with View.OnClickListener if it is an interface?
Thanks for your reply..
I'm not sure I understand what you are writing about static methods. View.OnClickListener is an interface: http://developer.android.com/reference/android/view/View.OnClickListener.html
To set a click listener on a view, you pass an instance implementing the OnClickListerner interface: http://developer.android.com/reference/android/view/View.html#setOnClickListener(android.view.View.OnClickListener)
The most common way to do this in android is to define an anonymous inner class (http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html) that implements OnClickListener like
myView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Handle view click here
}
});
The code above both defines an anonymous inner class and creates an instance of it. It is equivalent to first defining a class implementing View.OnClickListener (if defined in the same class)
class MyOnClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
// Handle view click here
}
}
And later using this
MyOnClickListener listener = new MyOnClickListener();
myView.setOnClickListener(listener);
Sample Code,
Internally it works something like this,
public class MyView{
public stinterface MyInterface{
public void myOnClick(View view);
}
}
public class MyButton{
View view;
public void setOnClicker(MyInterface onClicker) {
onClicker.myOnClick(view);
}
}
public class MyExample{
public void method(){
MyButton myButton = new MyButton();
myButton.setOnClicker(new MyInterface() {
#Override
public void myOnClick(View view) {
}
});
}
}