Hello I have a problem with opening Activity.
I'm calling startActivity() with Intent by clicking Button.
I need to wait 4-5 seconds before Activity shows up on the screen.
I know how to do.
itemimg = new ItemsInPacagesImageView(imglist1, this, nazovtripu, 0);
I have 17 times similar code (with other ImageViews) I have this in Method with name InitItemimg();
I tried put this method on OnStart activity with this thread
#Override
public void onStart() {
super.onStart();
timer = new Thread() { // new thread
public void run() {
Boolean b = true;
try {
sleep(20);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
InitItemimg();;
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
};
timer.start();
}
But is no resolve my problem, please do you have some ideas? Thanks
excuse me, I figured so in this method (ItemsInPacagesImageView(imglist1, this, nazovtripu, 0);) on start id deserialization if is some deserialization in row is "fast" but if it's more in row (now 17) with deserialization program spend more time some seconds.
I resolve this problem with put explicit, class which i deserialization in method.
Now i deserialization once instead 17 times. and I safe more miliscond-seconds.
Related
I'm new to Android and I'm working on a tiny project with a set of strict parameters. One of them is to have a multifunction button that increments a timer every time it's clicked, and that starts only after I didn't increment said timer for 3 seconds.
I found three or four ways on how to set an alarm of sorts with Handler, CountDownTimer, Timer, or some other way, but I'm confused on how I can do what I'm looking for with just the onClick() method.
The function to wait for 3s(), I'm calling it after:
public void wait3s()
{
Thread thread = new Thread() {
#Override
public void run()
{
while (!isInterrupted()) {
try {
Thread.sleep(3000);
runOnUiThread(new Runnable() {
#Override
public void run() {
count++;
threeS.setText(String.valueOf(count));
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
My onClick() just calls these:
public void onClick(View view)
{
increment();
wait3s();
startStop();
}
As you can see, part of the issue is that I'm calling the wait3s() there at every click, and I need a way to control that Thread/Timer (whatever) without it creating a new one at every click. I'm being a little dumb now, but I have been on this for a while and I'm still coming out empty, since I never worked with this before.
Another option for the wait3s() function that I found would be like in this other StackOverflow thread.
Thank you
PS: Sorry for the title, I couldn't find a better way to describe it, if you have it, and have the power to change it, please do.
Handler.removeCallbacks will effectively cancel a runnable.
boolean timerStarted = false;
clockHandler = new Handler();
OnClick(){
if (!timerStarted){
incrementTimer();
clockHandler.removeCallbacks(null);
clockHandler.postDelayed(new Runnable() {
#Override
public void run() {
// maybe kick off another handler/runnable here to start your timer
timerStarted = true;
}
}
}, 3 * 60 * 1000);
} else {
startStop();
}
}
Here's how I solve it. Although the suggestions were closer, they weren't exactly spot on to what I was looking for, in terms of logic, they weren't exactly helpful, creating more issues. Perhaps it's due to my explanation of the problem, perhaps because I'm new to Android Studio and the explanations shared here with me. Pardon me if it looks like I'm just using my own answer for internet points, I just had to put a lot more to understand this by myself than what I actually got from the answers shared here.
public void wait3s()
{
t.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
startStop();
}
});
}
}, 3000);
}
The variable t is a Timer(), and I had to import the classes java.util.Timer, and java.util.TimerTask. I called this method inside my increment() method and under onClick() I just have the increment() method. Turned out pretty neat.
I'm making an app in Android Java, using Android Studio.
Every 0.1 seconds I want to update the text within a certain TextView.
I already managed to use a Handler to execute a method every 0.1 seconds (100 ms), but it doesn't automatically update the TextView.
It only updates the TextView to what I want when the user interacts with the app. It only updates it when, for example, the user slides the SeekBar or presses a button. It doesn't update when the user clicks on the screen, and not automatically without input either.
How can I make it such that it will update the value automatically, without user input?
Thanks in advance.
P.S: I'm new to Android and Java, and I'm using threads to get the value, in xml format, from a website.
Should I post any code, and if so, what exactly?
you can try updating the value of text view on the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
//update TextView here
}
});
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
You can update your textview using thread also, like this.
int prStatus = 0;
new Thread(new Runnable() {
public void run() {
while (prStatus < 100) {
prStatus += 1;
handler.post(new Runnable() {
public void run() {
tv.setText(prStatus + "/");
}
});
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(prStatus == 100)
prStatus = 0;
}
}
}).start();
I'm new to Android and Java programming. I created an app for a Coursera class. It has two animations that occur repeatedly. I want them to animate like a drum beat - 1,2,1,2,1,2,1,2,1,2.
I wrote two recursive methods that run until the user clicks a Reset button. I tried adding a wait in between the method calls so the second would kick off right after the first one.
This is the part of my code that has the wait.
mHandler = new Handler(); // .os package class when importing
mLeftfoot = findViewById(R.id.leftfoot);
mRightfoot = findViewById(R.id.rightfoot);
mFootAnim = AnimationUtils.loadAnimation(this, R.anim.foot); //this looks to the foot.xml file for the animations
leftstepRecursive();
try {
wait(600);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rightstepRecursive();
This part of my code shows the recursive methods, which could probably be written better I know. A lot of DRY...
private void leftstepRecursive() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mLeftfoot.startAnimation(mFootAnim);
if (!pleaseStop)
leftstepRecursive();
}
}, mIntervalleft);}
private void rightstepRecursive() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mRightfoot.startAnimation(mFootAnim);
if (!pleaseStop)
rightstepRecursive();
}
}, mIntervalright);
Any better ideas to implement this left, right, left, right, left, right, left, right, left, right, idea?
Or, what I can do to correct the wait?
I also tried this:
private void rightstepRecursive() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
Object testobj = mRightfoot.startAnimation(mFootAnim);
synchronized (testobj) {
testobj.wait(600);
}
if (!pleaseStop)
rightstepRecursive();
}
}, mIntervalright);
#LuigiMendoza. I tried thread(sleep). No errors, but both animations move simultaneously not sure why...
private void rightstepRecursive() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mRightfoot.startAnimation(mFootAnim);
if (!pleaseStop)
rightstepRecursive();
}
}, mIntervalright);
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
I also get this message repeating in Logcat.
02-11 12:15:32.261: I/Choreographer(30480): Skipped 302 frames! The application may be doing too much work on its main thread.
You should really utilize the Animations framework and some of the classes it provides such as AnimationListeners and AnimatorSets. The Animations framework provides a lot of functionality that would really simplify what you are trying to do i.e. repeating animations, adding delays, timing animations, etc.
Here's a really bare bones example to give the basic idea:
AnimatorSet animations;
//Play the animation
private void playAnimation(){
//If they haven't stopped the animation, loop it.
ObjectAnimator anim1 = ObjectAnimator.ofFloat(target, propertyName, values);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(target, propertyName, values);
animations = new AnimatorSet();
animations.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
playAnimation();
}
});
animations.play(anim1).before(anim2);
animations.start();
}
//Called when cancel is selected
private void stopAnimation(){
animations.end();
}
I'm trying to make a simple little program that will increment a number once a second. In this case, I'm implementing a thread that should loop once per second and add 1 to "potato" each time it loops. This works fine until it gets back to the display method potatoDisp(). For some reason this causes my app to crash. Removing potatoDisp() from run() fixes the problem, but the display is not updated as "potato" increases.
public int potato = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
potatoDisp();
start();
}
public void potatoDisp() {
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("You currently have " + potato + " potatoes");
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
potatoDisp();
}
}
I'm doing this for an Android app, if that helps. I've tried searching for an answer but I'm pretty lost when it comes to the proper way to work threads.
You need a runnable / handler like this:
private Runnable potatoRun = new Runnable() {
#Override
public void run () {
potatoDisp();
}
};
then change
potatoDisp();
to:
runOnUiThread(potatoRun);
You can't update the views when you're not on the UI thread.
You are probably getting an exception for updating the UI in the background. Since, potatoDisp(); is called from a background Thread but that function updates the UI it will give you problems. You need to call it with runOnUiThread().
#Override
public void run() {
while (true) {
try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
#Override
public void run()
{
potatoDisp();
}
});
}
}
Something like this should work.
The issue is that you are trying to update the UI (calling text.setText(...)) on a thread other than the main UI thread.
While I would suggest using a TimerTask instead of calling Thread.sleep(...), there are two main ways to edit your current code to work as expected.
-- Use a Handler
Define a Handler class that will accept messages and update your UI as needed. For example:
private final String POTATO_COUNT = "num_potatoes";
Handler handler = new Handler() {
public void handleMessage(Message msg) {
int numPotatoes = msg.getData.getInt(POTATO_COUNT);
mText.setText("You currently have " + numPotatoes + " potatoes");
}
}
Then in your code where you want to call your handler to update your text view, whether or not you are on the main UI thread, do the following:
Bundle bundle = new Bundle();
bundle.putInt(POTATO_COUNT, potato);
Message msg = new Message();
msg.setData(bundle);
handler.sendMessage(msg);
-- Call runOnUiThread(...)
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
public void run()
{
potatoDisp();
}
}
}
}
I think you should be using Async Task to update the UI from a thread: http://developer.android.com/reference/android/os/AsyncTask.html
I wrote this app that in the first screen it has an included Thread on it. So it has I timed it like 7 seconds then it will proceed to the next activity.
The problem is whenever I hit the home button the music will stop and it will go to android homescreen but after my timed is done which is the 7 seconds, the app will reappear and will show the next activity.
I tried putting finish(); in the onpause(); but it's still showing the next activity.
here's the actual code.
public class HelloWorldActivity extends Activity {
MediaPlayer mp;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
mp = MediaPlayer.create(this, R.raw.otj);
mp.start();
Thread LogoTimer = new Thread(){
public void run(){
try{
int LogoTimer = 0;
while(LogoTimer < 7000){
sleep(100);
LogoTimer = LogoTimer + 100;
}
startActivity(new Intent("com.example.HelloWorld.CLEARSCREEN"));
} catch (InterruptedException e) {
e.printStackTrace();
}
finally{
finish();
}
}
};
LogoTimer.start();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mp.release();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mp.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
}
First, that's a really inefficient way to run a timer. Try this way instead:
new Handler().postDelayed(new Runnable() {
public void run() {
// Do some work.
}
}, delayTimeInMs);
Second, your starting a new activity when that timer eventually fires. It doesn't matter that the originating activity is finished. Your startActivity() is running on it's own thread and will execute regardless.
It's possible the postDelayed() method will function like you expect. If not you'll need to have it check when it runs whether it should really start the activity. However, I think the Handler is attached to the default Looper which means it will stop (or rather, the message won't be posted) if the main activity finishes.
The application is still in the background and the thread is not destroyed so it will fire the startActivity.
I would not really setup a splash screen this way, or use a thread unless I wanted it off the UI for some reason, even then there are better options.
For educational purposes to take care of this you need to be able to abort the thread safely in onPause() one way to do so is below
Modifed Thread
Thread LogoTimer = new Thread() {
private volatile boolean abortThread = false;
public void run(){
long stopAt = System.currentTimeMillis() + 7000;
while (!abortThread && stopAt > System.currentTimeMillis())
yield();
if (!abortThread)
startActivity ...
}
public synchronized void stopThread() {
abortThread = true;
}
};