I'm writing a simple chat application but i don't know how to use my main result handler from another activity. I'm setting resultHandler in main activity like this:
ResultHandler handler = new ResultHandler();
MGey.setUpdatesHandler(handler);
My ResultHandler.java has this code
public class ResultHandler {
#Override
public void onResult(ChatObject object)
{
//receive message object from server
}
}
Now in my other activity (Dialogs.java) I want to use this handler to get updates.
For example: if my onResult method receive new message object (ChatObject.NewMessage) I want to use this object in my Dialogs.java for new message notification etc.
if (object instanceof ChatObject.NewMessage)
//pass this object to Dialogs activity
Related
I am sending an object called event inside my application but to another process.
I am using IPC EventBus. When I register I cannot receive events back.
This is what I am doing:
public class UserActivity extends Activity
implements IIpcEventBusConnectionListener, IIpcEventBusObserver {
#Override
public void onConnected(IIpcEventBusConnector connector) {
connector.registerObserver(this);
}
...
}
How can I receive the events?
Are you calling conn.startConnection();? If you don't then it will not work.
IIpcEventBusConnector conn =
ConnectorFactory.getInstance().buildConnector(context, this, "com.myapp");
conn.startConnection();
I am sorry for my bad english skills. I'm new to programming/stackoverflow and try to create a little android quiz app. This app has to connect to a php server and login/getquestion...
The simplest example is the login. The user has to type in his data and then i have to connect.
To provide that the Gui doesnt freeze i have to use asynchronous tasks.
Here the activity's code:
public void login(final String username, final String password) {
final Activity a = this;
FutureTask t = new FutureTask(new Callable() {
public Object call() {
Connection.GetInstance(a).login(username,password);
afterLoginTry(username,password);
return null;
}
});
t.run();
}
This calls a method in another class, which calls another FutureTask which calls an AsyncTask. At the end there is always an public synchronized method such as afterlogintry(). This works but it's a bit slow and i think dirty code.
My main problem is that i don't know how to give results back through different layers of classes and especially to the activity without using hotfixes all the time.
Is there any good explanation or tutorial, which describes how to design such a construct?
Thx for help
The way you can pass AsyncTask results back to other classes, is by declaring callbacks for the task, that will then report the result to a listener. Here is how it works.
First, you must declare an interface in your AsyncTask which contains a method that will send out the result of the task. So in my example task below, my result is a String. The String gets passed to onPostExecute() when the task finishes its work. I then call my callback method on a registered listener, and pass that return value on to whoever is listening for it. You register a listener by passing in an instance of your callbacks from whichever class is creating the task.
public class MyTask extends AsyncTask<String, Void, String> {
MyTaskCallback listener;
public MyTask(MyTaskCallback listener) {
this.listener = listener;
}
protected String doInBackground(String... params) {
String input = params[0];
//do work
input += "did some work on this String";
return input;
}
//When the thread finishes its work, this gets
//called on the main UI thread
protected void onPostExecute(String result) {
listener.onResultReceived(result);
}
public interface MyTaskCallback {
void onResultReceived(String result);
}
}
So next we need to register a listener for these callbacks, so when the result comes in from the task, it will get reported directly to our class. So let's say we have a simple Activity. The way we register the callbacks is to use the implements keyword on our class declaration, and then to actually implement the callback method in the class itself. We then create our task, and we pass in this which is our Activity that implements the callbacks. A simple example Activity that does this looks like this:
public class TaskActivity extends AppCompatActivity implements MyTask.MyTaskCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
//we pass in "this" because our Activity itself
//implements the callbacks below.
MyTask myTask = new MyTask(this);
myTask.execute();
}
//Here we implement our callback method, so the task
//can send its results straight through here
public void onResultReceived(String theResult) {
Log.d("TASK RESULT", "Here is our result String: "+theResult);
}
}
Now, our task has our Activity connected to it, through the callbacks we passed into it. So now when our task gets a result, we can send it directly to our listener, which is our Activity, and the result will come right through to our implemented onResultReceived method.
Callbacks are a great way to pass information around between classes while also keeping everything very separated. Hope this helps!
you may know about Google Cloud Messaging
The problem is that when a gcm message triggers by the server, my application receives a bundle from google play services, this happen at GcmBroadcastReceiver.java. Here i can send this data to other classes in order to append some info from the server.. well. I got stuck when i try to update, for example, some views in the UI thread.
HOW I CAN DO THIS?
Imagine that MainActivity.java is the UI thread when i declare the views, etc.
I tried to create here a public static method which can be called directly by GcmBroadcastReceiver.java by this way: MainActivity.*updateUI*(args..), but it throws this exception:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Can anyone try to explain me this? i also know about asyncTask but i cant imagine how it works. I also find some pages explaining events that are fired by the UI thread it self like runnables that do some task in background. Im searching something like this:
MainActivity extends Activity{
...
protected void onCreate(Bundle blabla)..{
setContentView(R.layout.blabla);
registerSomeEvent(this);
}
private void handleEvent(Bundle ...){
... do stuff with the data provided in the UI thread
}
}
And here at GcmBroadcastReceiver, when gcm push some data, trigger that magic event in order to perform updates at the UI thread with some views like ListViews or TextView
One way is to use use LocalBroacastManager. For how to implement is, there is a great example on how to use LocalBroadcastManager?.
LocalBroadcast Manager is a helper to register for and send broadcasts of Intents to local objects within your process. The data you are broadcasting won't leave your app, so don't need to worry about leaking private data.`
Your activity can register for this local broadcast. From the GCMBroadcastReceiver, you send a local broadcast when you receive something in GcmBroadcastReceiver. Inside your Activity you can listen to the broadcast. This way if the activity is in the forefront/is active, it will receive the broadcast otherwise it won't. So, whenever you receive that local broadcast, you may do the desired action if activity is open. This is like saying to the activity that "Hey Activity, I've received a message. Do whatever you want with it".
If you want to do for the whole app, then you can make all your activities extend an abstract activity. And inside this abstract activity class you can register it for this 'LocalBroadcast'. Other way is to register for LocalBroadcast inside all your activities (but then you'll have to manage how you'll show the message only once).
You can use Handlers in your MainActivity in order to comunicate with UI Thread.
Communicating with the UI Thread
public class MainActivity extends Activity{
public static final int NEW_DATA_AVAILABLE = 0;
public static final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MainActivity.NEW_DATA_AVAILABLE:
String newData = msg.getData().getString(MyClass.DATA);
//Do some stuff with newData
break;
}
}
};
}
and in your non Activity class
public class MyClass implements Runnable{
Thread thread;
public final static String DATA = "new_data";
public MyClass(){
thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while(true){
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
Message msg = mHandler.obtainMessage(MainActivity.NEW_DATA_AVAILABLE);
Bundle bundle = new Bundle();
bundle.putString(DATA, "We have received new data");
msg.setData(bundle);
MainActivity.handler.sendMessage(msg);
}
}
}
I have a main activity where I create an adapter for a arraylist data.
I read the news from a website using a separate thread with Jsoup.
In onCreate() i have
this.newsItemAdapter = new NewsItemAdapter(this,
R.layout.newsitem_row,NewsItemAdapter.getAllNews());
parseThread.start();
this.newsItemAdapter.notifyDataSetChanged();
When i read from the adapter, i get empty list. This is because the thread is not completed yet. Any idea as to how i should proceed?
I cannot do notifyDataSetChanged inside my thread because it is not the owner of the adapter.
You need to notify after the seperate thread finishes, and invoke notifyDataSet on UI-thread, one possible method is to use handler,
you can define a handler in activity, invoke notifyDataSet change in handleMessage, such as
handler = new android.os.Handler() {
#Override
public void handleMessage(Message msg) {
newsItemAdapter.notifyDataSetChanged();
}
}
and in the thread run method, you need to send a message to the handler,
public void run() {
// add this to the end
Message msg = new Message()
handler.sendMessage(msg);
}
or else you can use AsyncTask instead of seperate thread, use jsoup in task's doInBackground method, and notifyDataSet in onPostExecute.
The handler document is http://developer.android.com/reference/android/os/Handler.html, and AsyncTask's is http://developer.android.com/reference/android/os/AsyncTask.html.
Pass the adapter to your thread in its constructor. Then your thread can call notifyDataSetChanged.
I am creating an application which relies on data backend over Internet connection. This data is common between activities. Also, data will be kept refresh e.g. by updating it every two or three minutes. Therefore, I have created a data handler class, which should handle everything related to data downloading, parsing and such. Sometimes, it will receive command from Activity to refresh the data.
The problem is, how to refresh the UI in the activity when new data becomes available in the datahandler. If the datahandler was in activity, I could just post a handler for UI thread to update it. However, I don't know how to do it from this underlying class. Any advice?
Here's the rough code for three classes:
/**
* The data handler class itself
*/
public class DataHandler {
Object data;
public void getData () {
// starts a thread (HTTP query) to get data
}
private class dataReceived (Object data) {
// receives data
this.data = data;
// TRIGGER updateUI() in MyActivity! HOW?
}
}
/**
* Application class. I'm planning to keep data handler here, and reference it from activities when required.
*/
public class MyApplication extends Application {
private DataHandler dataHandler;
public DataHandler getDataHandler() {
return dataHandler;
}
public void onCreate() {
DataHandler dataHandler = new DataHandler();
}
}
/**
* Activity
*/
public class MyActivity extends Activity {
DataHandler dataHandler;
public void onCreate(Bundle o) {
dataHandler = ((MyApplication) getApplication()).getDataHandler();
}
public void onResume() {
// trigger data refresh (OBS! This could also be by a button press etc.)
dataHandler.getData();
}
public void updateUI() {
// UPDATE UI
// should be called on DataHandler when data is received. HOW?
}
}
Register your activity as a listener to the DataHandler and when the thread recieves data invoke any listeners.
How are you presenting the data? If it's a ListView with an ArrayAdapter, then simply invoke the notifyDataSetChanged() on it as you get an update.
You'll have to make sure you update the UI in an appropriate UI thread, of which there are many ways. One that springs to mind is you could create a blocking AsyncTask that receives the listener events, unblocks it's background thread and runs its publishProgress() to ensure the update happens on the UI.