I have a program which automatically moves objects around the screen, drawing them on an ImageView. On some occasions, two or more objects will be moved in succession. At present, the user sees only the final configuration. I would like to insert a pause between them, so that intermediate configurations are seen.
The code below is intended to achieve this by setting a busy flag and sleeping on a separate thread. However, it does not update the screen in between. The effect is a long pause followed by the final view.
Advice would be welcome!
private boolean busy = false;
private void slowMoveObject(<args>) {
Thread th = new Thread() {
public void run() {
int waitCount = 0;
while (busy) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
waitCount++;
if (waitCount > 50) break;
}
busy = true;
moveObject(<args>);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
busy = false;
};
};
th.run(); // delay
}
Related
I have a little problem. In my android app, i have to connect to an online server.
The connection should be called with an click-button an as an backround service. I know that I must put the network connection in a thread, but i don't know how it works.
I put the call in a own method wich creates a thread but at compilation i got a error message.
here is my code:
Button:
ImageView refresher = (ImageView)findViewById(R.id.imgRefresh);
refresher.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
httpThread();
}
});
thread method:
private void httpThread(){
final Handler h = new Handler();
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
h.post(new Runnable(){
#Override
public void run() {
try{
vomServerholenUndSpeichern();
FileInputStream inStream = null;
try {
inStream = openFileInput("test.xml");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
leseDatei(inStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createListView("test.xml");
System.out.println(inStream);
drawListView();
} catch (Exception e){
e.printStackTrace();
}
}
});
}
});
thread.start();
}
Can someone help me to fix the problem?
You have to use AsyncTask, is not difficult.
AsyncTask are necessary to avoid block UI during your connection operation, the method doInbackGround of AsyncTask is used for this kind of operations (it runs in a thread different from the UI), while int the onPostExecute (this run on the UI) of the task you will manage your httpResult;)
I am trying to run audios one after another with a time gap of 5 seconds. However I dont really see that happening. My third audio in the list is played and others are skipped. This means while debugging only music3 is being played and others are not. I would love alternate methods of doing this. Moreover I used prepare method just like that. Makes no difference while running though.
for(int j=0;j<3;j++)
{
if(j==0)
{
xnp = MediaPlayer.create(this,R.raw.ticktock);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
}
if(j==1)
{
xnp = MediaPlayer.create(this,R.raw.music2);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
}
else if (j==2)
{
xnp = MediaPlayer.create(this,R.raw.music3);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
try {
xnp.prepare();
xnp.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
xnp.stop();
intenter();
}
}
Your current implementation does not work because the media playback is not done on the main thread, so you are immediately playing all 3 media resources, so only the third one is heard.
I think you might want to call MediaPlayer#setOnCompletionListener on your MediaPlayer object. In the completion listener, you can then postDelayed onto your Handler to queue up the next resource to play.
I need animate menu in custom view. It must be redrawed with intervals some times(about 10), but it redraws after thread stopped.
public void menuShift() {
Runnable runnable = new Runnable() {
public void run() {
while (TablesActivity.this.view.menuShifting) {
try {
Thread.sleep(100) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TablesActivity.this.view.timerRefresh() ;
TablesActivity.this.view.postInvalidate() ;
}
}
} ;
this.menuShiftThread = new Thread(runnable) ;
this.menuShiftThread.run() ;
}
this.menuShiftThread.run(); is the problem, you need
this.menuShiftThread.start()
to actualy start a new thread.
So I am trying to create a "strobe" light effect in my app.
To do this I need a time delay, one of 100ms the other of 20.
Here is the code I'm using.
Thread timer = new Thread();
long longTime = 100;
long shortTime = 20;
for (int x = 0; x < 2000000; x++)
{
layout.setBackgroundColor(background);
try {
timer.sleep(longTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
layout.setBackgroundColor(backgroundBlack);
try {
timer.sleep(shortTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The issue I have is that when I click the button to call that code, nothing happens. So I've done a bit of debugging and am pretty sure it is the timing call. I have never programmed in Java before so I am unsure how to call a Thread Sleep.
You could use a Handler as below to achieve this.
public class Strobe extends Activity {
private LinearLayout mLinearLayout;
private Handler mHander = new Handler();
private boolean mActive = false;
private boolean mSwap = true;
private final Runnable mRunnable = new Runnable() {
public void run() {
if (mActive) {
if (mSwap) {
mLinearLayout.setBackgroundColor(Color.WHITE);
mSwap = false;
mHander.postDelayed(mRunnable, 20);
} else {
mLinearLayout.setBackgroundColor(Color.BLACK);
mSwap = true;
mHander.postDelayed(mRunnable, 100);
}
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLinearLayout = (LinearLayout) findViewById(R.id.strobe);
startStrobe();
}
private void startStrobe() {
mActive = true;
mHander.post(mRunnable);
}
}
Set a Theme to the Activity to make it full screen.
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
I think this article would benefit you.
http://oreilly.com/catalog/expjava/excerpt/index.html
specifically this
http://oreilly.com/catalog/expjava/excerpt/index.html#EXJ-CH-6-FIG-1
Your problem is that you are not running in the Thread. In order to run code in the thread you must override it's run() method. Based on your current code, the following may capture what you want to do.
Thread timer = new Thread(){
public void run(){
long longTime = 100;
long shortTime = 20;
for (int x = 0; x < 2000000; x++)
{
layout.setBackgroundColor(background);
try {
Thread.sleep(longTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
layout.setBackgroundColor(backgroundBlack);
try {
Thread.sleep(shortTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
timer.start();
However, threads don't play that well with the Android OS. For your application, it may be better to use Android services. See http://developer.android.com/guide/topics/fundamentals/services.html .
i could need some help with that. here is the problem and what i have done until now.
problem:
i want to play a pcm file that i recorded before. as this file can be larger, i play it by using audiotrack. this works quite nice. but i dont want the activity to freeze. i already tried thread and so on, now im working on the asynctask but the activity still is not responding.
this is what i got:
in the ui activity, i create a new waveplayer object and try to run it.
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* Handles ShortClicks for ListView
*/
OnItemClickListener itemlistener = new OnItemClickListener(){
MediaPlayer mp=null;
String currentlyplaying = null;
#Override
public void onItemClick(AdapterView<?> adaptview, View clickedview, int position,
long id) {
String pathtofile = (String) adaptview.getItemAtPosition(position);
if(pathtofile.contains(".wav"))
{
//HQ!
if(mp==null)
{
clickedview.setSelected(true);
try
{
WavePlayer t = null;
//TODO: //add thread waveplayer to play file!
try {
t = new WavePlayer(pathtofile);
t.execute((Void)null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clickedview.postDelayed(new Deselector(clickedview, t), 1000);
currentlyplaying = pathtofile;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
else
{
}
}
else{
//NO HQ
//you dont need to know that :)
}
}
};
the class deselector:
/**
* This Runnable tries to deselect the view after playing the audio file.
* #author quant
*
*/
class Deselector implements Runnable
{
View view = null;
AsyncTask thread;
Deselector(View view, AsyncTask t)
{
this.view = view ;
this.thread = t;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
view.setSelected(false);
thread.cancel(true);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
everything concerning playback works nice, i can hear my voice and the playback itself works fine... but still the gui in the main activity does freeze/is not responding.
hope someone can help.
thanks in advance
markus
i solved it by using a remote service. i'm happy with this solution because i had one running for other purpose yet. now the interface is responsive again.