How to set the values in Textview of MainActivity from simple class - android

I have two classes One is MainActivity.java and other is simple Java class ConnectMe.java. I have Single Button and Single EditText on MainActivity. I am using a button to Login So it is named also as btnLogin. On its clickListener, I am taking the Ip from the EditText(in string format) and calling the Login function from the ConnectMe.java class which takes string as a parameter.
Now in ConnectMe class I check if the application is connected to the server it should show the Connected Message in EditText and Also it should show the Toast on MainActivity. And I have no Idea How to do this as I am new to android.
here is my sample code
public class MainActivity extends Activity {
Button btngLogin;
EditText etIp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnLogin.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
ConnectMe connectMe = new ConnectMe();
connectme.LogMeIn(etIp.getText().toString);
}
});
}
here is my java class for connection
public class ConnectMe {
MainActivity mainActivity = new MainActivity();
void LogMeIn(String ip){
MyConnectedmethod.Connectednew (new Runnable() {
public void run() {
mainActivity.setText("connected");
}
}
I know the code is not proper, But I just want to give you an idea. I am getting the null point exception on the line in which I am setting text of EditText.
With some research, I have find out that I can not touch the views from the Thread and Runnable directly . and I was told to use runOnUiThread. like mainActivity.runOnUiThread but it is also not helping giving error of nullpointexception.
So Please help me as I am new to android programming

A lot going on here.
There's basically no instance in which you should instantiate an activity.
The Activity doesn't have a .setText() method. So that's the null pointer.
There's a much easier way to do a simple worker task than creating your own thread and managing it yourself. Use AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
EDIT:
You can run as many AsncTasks as you like. Without more context, it's hard to say exactly what your best approach is. But, it sounds like you probably want to run some kind of service. (http://developer.android.com/reference/android/app/Service.html). There's a couple different flavors available, depending on what you want to do. If it needs to run all the time, rather your app is running or not, then use a start service. If it needs to run only so long as the UI is going, then a bound service is the option. If it needs to do something every so often than some combination of intent service/broadcast receiver/alarm manager is the route.
You may not even need a service. If you're just loading several things use the loader manager. For downloading content a SyncAdapter may be the way to go. The point is that after 24APIs most common tasks already have a ready made solution. So, in most cases, you don't need to fiddle with threads yourself.

The NullPointerException happens because you`re missing to declare what object Button btngLogin refers to.
btngLogin = findViewById(R.id.yourbuttonnameinxml);
Do the same with your EditText.

i think you better read this first, starting another activity with intents and sharing a message between two activities (classes): http://developer.android.com/training/basics/firstapp/starting-activity.html

Related

Can i listen to an event in class A which is fired in aSyncTask, without implementing interface in class A?

First of all i will apologize for the bad question formulation, i don't know how to ask is on a more clear way, so suggestions are welcome!
I'm new with android and struggled a lot with aSyncTask for getting some XML from the web. Downloading the XML and pass it to the class who invoked the aSyncTask works fine now.
The problem i have is that i only can listen to the event which is fired in the aSyncTask > onPostExecute method when i put "implements Interface" on the class who invokes the aSyncTask class. I'm interessed to an way where i dont need to implement the interface. I think this is posible becouse the default objects such as buttons and so on can be listened to witouth implementing something.
Maybe i think completely wrong about this all?
The way i set up my own event handler/listener is:
Creating an listener
public interface XmlUpdateListener {
void onXmlUpdate(String result);
}
Invoke the listerner in the aSyncTask class
public XmlManager(XmlUpdateListener delegate) {
this.delegate = delegate;
}
#Override
protected void onPostExecute(String result) {
delegate.onXmlUpdate(result);
}
Listen to the event in the class who invokes the aSyncTask class
public class XmlDataLayer implements XmlUpdateListener
#Override
public void onXmlUpdate(String result)
{
this.XML = result;
}
I searched for a lot of videos on youtube and a lot of articles on the internet. There are many many ways explained but i don't realy understand one completely. Here on stackoverflow i found a lot of articles but the most of them has no 100% clear answere for me. Maybe someone has a lot of patience to make me this whole stuff clear for ever by give me some sample code and explain me what happened. I'm a person i need to know how it works and why it works like that, then i understand it else it is a big mess in my head and can't still understand.
---------- Edit: Added some extra info about my problem ----------
My problem is: from UI i call an dataclass, this gets starts the aSyncTask and get its response over the upstanding mechanism. From there i need to trow an event that can be used on several places. I will catch this event for updating the UI and updating the internal database. The problem is that my UI class extends the AppCompatActivity and i cant implement the interface there to catch the event. That's the reason why i need to catch an event without implementing something. I think something like new XmlManager(..).exe(); looks good but cant get it done without "implements XmlUpdateListener"

Android/Java: Change view from another class?

There are two classes. MainActivity, in which i set the view, and ClassX from which i want to update a view in MainActivity. ClassX is an AsyncTask called from MainActivity, if that's relevant.
What i want to do is to change the text of a view called mainTextLog. I've declared a global TextView variable, and in the onCreate() method i set it to the view using findViewById().
private TextView logger;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
logger = (TextView) findViewById(R.id.mainTextLog);
}
By now i should be able to change the text from onCreate(), and i can. But since i want to change it from another class (ClassX) i need to create a method for it:
public void setLogText(String text) {
logger.setText(text);
}
But it doesn't work. I've tried making logger and the setLogText() method static, but it still doesn't work. The app just crashes.
It's probably pretty easy, but i'm out of ideas.
If you are using an AsyncTask you need to set the value in either onProgressUpdate or in onPostExecute.
You really should read the documentation for AsyncTasks
You CANNOT update the UI from the doInBackground method as it is not run in the UI thread and will give you an exception.
Also, you should post the exception you are getting when the application crashes so we have a better idea what the problem is. But I'd guess you are trying to update the text from the wrong thread.
I've done this plenty in the app im working on, its sort of an MDI type app on the android tablet.
To do what you're asking....
in MainActivity have
public static void setText(String txt){
((TextView)findViewById(R.id.mainTextLog)).setText(txt);
}
then in the child (or calling class) call it like...
MainActivity.setText("myTextToShow");
That's it... im using android api level 12... If i remember correcty it worked in api level 7 as well though.
Hope this helps...
One possibility is that: when you call setLogText in another Class X. The MainActivity may not be existing anymore, which makes the logger a null reference?

onActivityResult outside of an activity scope

I'm trying to create an android project that contains shared code which will be used by others.
In this project I only have POJO and no android specific classes.
Some of the functionality requires calling some activities and is depended on the result.
My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.
My problem is that with the reference of the calling activity I can startActivityForResult but I have no way of adding the onActivityResult, which might exists in the calling activity but is not aware of the requestCode I used.
My question then is how do I know, from within a regular java object when the activity has returned? since, as far as I understand I can only implement onActivityResult on Activity classes.
thanks!
You will have quite a few problems with this setup, but this is how you might want to get started:
You will have to include an activity in your project which does nothing else than starting the activity you want to get the result from and stores it in a globally accessible storage (e.g. a singleton or a static field).
class Pojo {
static final ConditionVariable gate = new ConditionVariable();
static int result;
int m(Context context) {
context.startActivity(new Intent(context, ForwarderActivity.class));
gate.block();
return result;
}
}
class ForwarderActivity extends Activity {
private boolean started = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!started) {
started = true;
startActivityForResult(new Intent("ContactsProvider"), 1);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Pojo.result = resultCode;
Pojo.gate.open();
}
}
There are a couple of problems, though. Like your POJO's method can't be called from the main (UI) thread, because you need to convert an asynchronous call (startActivityForResult()) to a synchronous one (Pojo.m()) and the activity you want to receive info from will be started on the main thread, so you can't block it in Pojo.m()...
Anyway, the code does not work, but you can see which way to go if you really have to stick with this setup. But you should really try to come up with some other means of fetching the data, like a content provider.
i have the same problem while i play with UNITY3D,the unity have it's own Activity(the unity player),i don't wanna edit it for some reason. but the player activity do nothing inside the "onActivityResult" function. And i have something to do when access image picker,i can call "unityPlayer.startActivityForResult" to open image picker,but NO WAY TO CODE MY OWN "onActivityResult".
i think what we hope is something like this:
OtherActivityClass.onActivityResultListener=function(){My Own CODE}..........OR
OtherActivityClass.onActivityResultListener.add(myResultListener)..................
My question then is how do I know, from within a regular java object when the activity has returned?
Have the activity call the POJO, supplying the result.
My POJO classes get reference to the calling activity when used, but that's happening at run time and I have no control over the implementation of those activities.
Then whoever is in "control over the implementation of those activities" will need to have the activity call the POJO, supplying the result. This is no different than any other callback/listener mechanism.
Maybe PendingIntent http://developer.android.com/reference/android/app/PendingIntent.html can help you with that. I'm still looking around for a solution to my problem and for me, this class looks quite promising.
Another way might be to make your own class abstract and have a method onActivityResult that is required to be overridden. Of course, you would have to rely on JavaDoc and "please call super.onActivityResult" to be able to process the result in your code. But if the users of your class want to have some success with your code they should follow your JavaDoc instructions.
Similar to what Szabolcs Berecz suggests, it is possible. There is no beautiful solution, but following is possible:
create a simple no view activity that starts the intent for you
distribute the result through a global listener manager where interested classes can register and unregister theirself (the POJO e.g.)
this is non blocking but startActivityForResult and waiting for its result is non blocking in general
I've set this up in a library for app settings and some settings do start a system intent (e.g. select an image) and need to wait for their result and this works even after screen rotation without the need of any code adjustments by the libraries user.

Sending an Activity to a non-Android class

I'm pretty much a noob when it comes to Android development. I have an Activity that has a method that pretty much just sets the text of a TextView to whatever text is provided as an argument. I have a second class, which is a Runnable, and I want to be able to give it the Activity (or obtain the Activity somehow), so it can call said method when it needs to.
This Runnable will eventually connect with a server, so it can update the application with information from the server. I've done client/server Java stuff before, so that's not the issue. I just need to figure out how to communicate between this Runnable and the Activity.
Originally, I was going to just pass the Activity itself in, but I read that it would create problems if I did. Instead, I was supposed to pass in an ApplicationContext via getApplicationContext(). I did that, but now I don't know what to do with the ApplicationContext. I tried casting it to the my Activity class, but the program just crashes.
How do I accomplish what I'm aiming at?
There are a few specific ways in Android to handle threading like AsyncTasks etc., you should read up on how to do 'painless' threading here. If it's just a one-off task where you connect to the server, get the value, set it in the TextView and then finish, I think an AsyncTask would be your best option. Continuing background processes are more suited to being services.
you can pass your activity to the constructor of your second Class like this :
public SecondClass(YourActivity _yourActivity){
this.activity = _yourActivity;
//do stuff
}
and in your Activity , you can instanciate your class like this :
SecondClass instance = new SecondClass(this);
NOTE : in your SecondClass , if you want to change the UI of your application , you can use the method runOnUiThread(Runnable);

Activities interactions in Android

I am working on an Application that require some interaction between two activities, and I am not sure of what is the best way to achieve it:
One of the Activities is a "Logbook" (Just a ListView that displays a bunch of events).
The other Activity allows the user to create the events, that will be sent (and displayed in the Logbook).
How do I notify my Logbook Activity when a new Event is ready to be added?
Also, where should I add the event to the database? From the Logbook Activity, when I add it to the ListView, or from the NewEvents Activity, as soon as it's ready?
Thanks!
Ok, I found how to do it, using a BroadcastReceiver:
In my Logbook activity, I just set up a new custom receiver onCreate():
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logbook);
registerReceiver(new EventReceiver(this), new IntentFilter("SEND_NEW_EVENT"));
Now, I can make the calls in my newEventActivity:
public void sendToLogbook(int eventId){
Intent i = new Intent("SEND_NEW_EVENT");
i.putExtra("newEvent", this.newEvents[eventId]);
sendBroadcast(i);
}
Of course, I had to create my CustomReceiver Class, and override the onReceive() method to do what I want:
public class EventReceiver extends BroadcastReceiver {
private ActivityLogbook activity;
public EventReceiver(ActivityLogbook activity) {
this.activity = activity;
}
public void onReceive(Context context, Intent i) {
this.activity.addToReport((Event)i.getParcelableExtra("newEvent"));
}
}
It works great so far, but if you do have comments/concerns about this, please tell me!
Thank you!
If I recall cporrectly the Notepad project which is included in the android sdk and is also part of the tutorials online is a good examaple which should satisfy your needs.
To borrow from MV-* (Model-View-something or other) patterns, separate your idea of the Model (in this case, your Event objects) and what is displaying them (the View, or in your case an Activity) and it'll become more clear.
If you have your events somewhere global where all activities can interact with them, then you can work with the model and display the model from wherever and however you choose.
One simple suggestion is have a class (EventController or something like that) that allows you to interact with the Events collection, and make it available through a derived Application class. I can explain further if that doesn't make sense. I have a pattern I use in my Android apps whereby all Activity classes have access to a custom global Application instance, so my model is a model and can be accessed by whatever Activities I want to have access.
This is merely one approach, and as always, there are many that may suit your needs.
One possibility would be:
The ListActivity gets all the data each time it is resumed and updates the ListView accordingly
The NewEventActivity does all the job of storing the Event and simply finishes
You can improve it a bit more:
The ListActivity gets all the data when it starts
The ListActivity starts the NewEventActivity expecting a OK/CANCELLED result
The NewEventActivity does all the job of storing the Event and returns a result saying OK or CANCELLED
Depending on the result it gets from the NewEventActivity, ListActivity reloads its data or not

Categories

Resources