I have a custom table layout where each row is a slide-able view. Everything is working fine, except there is a continuous delay between when a user starts sliding a when the view starts moving. Is there a way to reduce that starting delay?
I am building my table layout inside an async task. So at first I was getting an error about needing to use a looper. Since I didn't know how to do that I use runOnUiThread to handle the problem code. So now I am wondering if that's the reason for the slow response to touch. Here is the code
activity.runOnUiThread(new Runnable() {
public void run() {
handler.post(mResizeViews);
}
});
The question may be "What happen when user sliding?"
if you do some heavily task such as inflate layout when user start slide.
So, check what happen when user start sliding
Related
I have an activity that gets started by a background service in order to show scrolling message(s) that the service receives from a server. It's possible to have just one scrolling message or a set of multiple to scroll, one at a time.
My question is what is the ideal way to manage cycling the scrolling of multiple messages, and multiple sets of multiple messages? I've tried my cycler loop within worker threads, AsyncTask, etc.
The Details:
My scroll activity receives the message(s) to show, as an array of strings available for it to access from the service's scope. Say, for example, the service starts the activity in order to scroll several messages, one after another:
My service populates MyService.messages[] with the messages to show and then starts MyScrollActivity.
MyScrollActivity gets size of MyService.messages[]. If >1, start MyCyclerThread (or AsyncTask, etc. - haven't figured out best way!)
MyCyclerThread loops through MyService.messages[] and sets MyScrollActivity TextView with messages[i] and animates across screen once, one message-iteration at a time (one message scrolls across, then the next, etc. - at end of loop, it starts over at i=0 and repeats the messages again.
Step 3 repeats until activity is taken down by the service or another activity is shown. The cycler-thread (or whatever - the loop) needs to die at this time.
I want that particular worker thread (that's doing the looping) to die and never come back whenever its activity stops. But for some reason, whenever the activity is restarted (say a new batch of messages comes in to display), the old cycler/worker thread resurrects, along with a new one for the new messages.
I've tried adding Thread.currentThread().interrupt() to the activity's onPause and onDestroy methods, and I see in my logging that the thread does get interrupted. But like I said, it resurrects (even with the same ID it had before) and starts its loop again. This means for however many 'X' times I start my activity, I also get 'X-1' number of threads running.
I toyed with Activity single-instance XML, various "isThreadABCrunning" flags, etc. I've even tried using an AsyncTask for my cycler loop. I'm running out of ideas.
Help, I'm beginner/intermediate in Android... I know just enough to make trouble, apparently. Is there something I'm missing about threading or activities? Is it perhaps something as simple as handling my activity differently?
I'd appreciate a 30,000 foot overview, and then I can provide code samples, as needed (I've gone through too many iterations to pin down one to post here for now), so sorry if I'm treading close to violating a post's best-practice.
Update: animation code
slide = new TranslateAnimation(dm.widthPixels, -params.width, 0, 0);
slide.setDuration(animDuration);
slide.setRepeatCount(repititions);
slide.setRepeatMode(Animation.RESTART);
slide.setInterpolator(new LinearInterpolator());
slide.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
msgIsScrolling = true;
}
#Override
public void onAnimationEnd(Animation animation) {
msgIsScrolling = false;
}
#Override
public void onAnimationRepeat(Animation animation) {
//nothing to do
}
});
textView_message.startAnimation(slide);
My gut reaction is that "multithreaded" solutions are the wrong way to approach this problem. My first thought is:
Change your design so that the activity just asks the service for the "next" message to show (the activity shouldn't know about how many messages or what message index it's on, it should just show whatever message the service gives it).
Use an Animator.AnimatorListener's onAnimationEnd() method to re-trigger your animation.
Essentially, you'd have some method inside the activity that takes a message and starts it animating. You'd call this method both when your activity is first shown and whenever a message is done scrolling.
Since this all lives inside the activity itself, there shouldn't need to be any cleanup when the activity dies.
is there anyway to listen on UIevents such as button click on main/ui thread? without interacting directly on each UI's callbacks(e.g onClickListener) ?
I just want to listen to any thing it fires from ui events, I've been digging around but I only find something that posts message to the ui thread from another thread, what I want is just listen to UI thread when for example a button is clicked,
findViewById(R.id.button_1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// some button click stuffs here
}
});
// this is where I want to listen from ui events (e.g click),
// and determine what type of view that triggered that event
// or how to get the actual view object that triggered it
I'm assuming that this could already be asked(It will be fine if this will be marked as duplicate, but please provide a related post if there is/are), every time I try to search for something like "listen to main thread", I cant find something like what exactly I need, Any help would be greatly appreciated, or any related links.
Edit: the current situation is, there is no way for me to interact with an existing code, so I'm trying to find a way to listen on those UI events without touching the actual codes(via separate module/library), I dont know if this is possible to achieve though
i think there is no direct way to do that, if you want to handle it outside, use the Handler
I'm using getDecorView().getWidth() to determine the sizing of some elements of my UI. Yes, I know this is a hacky approach, but I've found it to be the only reliable way to determine the actual usable width of the screen (subtracting, for example, the nav bar that is visible on the right hand of the screen on the Kindle Fire HD in landscape). The problem is that when the device's orientation changes, calling this method immediately after results in the incorrect value. Calling this same method just a split second later (by posting a delayed runnable) returns the correct value, but this approach is sort of a hack on top of a hack. Is there any way to find out when decor view is "ready" to return the correct value to me?
I believe although im willing to be wrong if you run your request on the UI thread using the runOnUiThread of an activity it should do what you want, things can only happen on the UI Thread sequentially so this call will be queued until the animation completes.
runOnUiThread(new Runnable() {
#Override
public void run() {
//code that needs to run on UI thread
}
});
I am experimenting with an app I am developping.
When I launch the app, there is currently a 3 second delay before the app UI is usable. During the delay the screen is black, apart from the task bar and, below it, the app title bar.
I was thinking about displaying a splashscreen as a dialog in the main Activity. However, it is only displayed after those 3 seconds, which makes it useless. This means that nearly all of the 3-second delay takes place between the launch and the call to
super.onCreate(savedInstanceState).
Can anyone educate me on what is happening behing the scenes during this delay ? Is there anything I can do to shorten it ?
Try to locate the slow code and put it into a second thread.
new Thread(new Runnable() {
#Override
public void run() {
// slow code goes here.
}
}).start();
I'm developing my first app for Android and its supposed to be a game. Everything is fine but there's one thing I just can't wrap my head around.
In my game's "main" activity (not the first activity which starts when the app starts) I want to have a method which starts a thread which changes a buttons background color/image (go with color because I haven't made any images just yet) for one second then turns it back. I wan't the method to also have an integer parameter which makes it perform this n times. I want to be able to call like changeButtons(5); and it turns button x background blue for 1 second then waits 1 second five times.
So practically I'm trying to make a "main" thread which runs during the game and inside that thread I'm going to run this method whenever certain conditions are true (a thread which calls a thread).
So I have 2 questions. The first one is "Is this possible? " and If so can someone show me how to do it (not all of it of course but help me get started at least)? Especially I want to know if I can change a buttons background color in a thread and if so can someone show me how to write/get me started that thread?
The second question is a follow-up, if you can do this, can you have a like a boolean b which turns to true if someone presses a button and the thread can "notice" that change? For example, if the thread is running and Obama presses button x and b turns "true" in the method OnClick(View v) can I, inside my main thead have an if(b == true){Obama.moon();} and Obama will moon?
Sure you can.
In android you can use the Handler class (example available) to post actions to the event queue. You can do something like this:
final Handler handler = new Handler();
final Runnable updateRunner = new Runnable() {
public void run() {
// we are now in the event handling so to speak,
// so go ahead and update gui, set color of button for instance
}
};
new Thread(new Runnable() {
public void run() {
while (condition) {
SystemClock.sleep(1000);
handler.post(updateRunner);
}
}
}).start();
This will trigger the run in updateRunner each second.
Regarding your follow up, it can be done as well (of course :) ). You can for instance implement an observable pattern to the class that handles the button x. When pressed, notify the observers with something like observers.updateChange(b)
where you previously had a thatClassOverThere.registerObserver(this) in your main thread.