Worker thread in Android - java

Hello im trying to simulate a worker thread in Android for testing.
The activity has a button that calls notify() over the worker thread, and I want it go to sleep after 10 iterations of the bucle.
Thats my code and the stacktrace of the error. How can I solve it? Thanks
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t= new Thread(){
public void run(){
int i=0;
while(true){
if (i%10==9){
//Simulated end of data until notified again
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d("Test",""+i);
SystemClock.sleep(1000);
}
}
};
t.start();
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.notify();
}
});
}
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): FATAL EXCEPTION: main
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): java.lang.IllegalMonitorStateException: object not locked by thread before notify()
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at java.lang.Object.notify(Native Method)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at com.example.memorycrash.MemoryCrashTestActivity$2.onClick(MemoryCrashTestActivity.java:51)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.view.View.performClick(View.java:2538)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.view.View$PerformClick.run(View.java:9152)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.os.Handler.handleCallback(Handler.java:587)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.os.Looper.loop(Looper.java:130)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at android.app.ActivityThread.main(ActivityThread.java:3687)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at java.lang.reflect.Method.invoke(Method.java:507)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
08-06 05:39:45.320: ERROR/AndroidRuntime(4480): at dalvik.system.NativeStart.main(Native Method)

So here is your solution.
Answer was already there on StackOverflow.
In order to call wait(), notify(), or notifyAll() on an object you must first own the monitor of the object you wish to call the method on, so in you case within the runnable this would be how you would need to do it:
Runnable runnable = new Runnable() {
public void run() {
// wait(); This call wouldn't work
syncronized (this) {
wait(); // This call will work
}
}
};
To notify that runnable you would also have to have the monitor
// runnable.notifyAll(); this call will not work
syncronized (runnable) {
runnable.notifyAll(); // this call will work
}

Related

Camera crashes if powerbutton pressed before picturecallback returns

Following problem: if I press the power button after pressing a take picture button just before the getPictureCallback() methode is called the app crashes.
The camera is loaded in a thread like this:
private class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
CameraHandlerThread() {
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened() {
notify();
runOnUiThread(new Runnable() {
public void run() {
setCameraParameter();
}
});
}
void openCamera() {
mHandler.post(new Runnable() {
#Override
public void run() {
openAndroidCamera();
notifyCameraOpened();
}
});
try {
wait();
}
catch (InterruptedException ex) {
LogManager.e(TAG, ex.getMessage(), ex);
CoreToastDialog.showErrorMessage(getString(R.string.FailedToLoadCamera));
}
}
}
I interrupt the thread in onPause. Any ideas how to fix this? The bug only occures in a very rare time shift - so only every 30 tries it works maybe once.
If it is PictureCallback, is there any way to fix this?
Error Message:
W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x410a32a0)
W/System.err﹕ java.lang.RuntimeException: Unable to start activity ComponentInfo{DeviceListView}: java.lang.NullPointerException
W/System.err﹕ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
W/System.err﹕ at android.app.ActivityThread.access$700(ActivityThread.java:140)
W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:4921)
W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)

Extending HandlerThread and when to call getLooper()

I have a simple Activity with a button on it. Upon the button's onClick method, I want to run some code in another thread, getting a HandlerThread's Looper object and then posting a Runnable to the Handler associated with it.
My objective is to call a thread's method from another thread (and run it from its own thread) using Handlers (probably a bad idea, but I wanted to learn this instead of abusing static methods)
So I decided to extend HandlerThread. The new class does not really do much.
public class EpicThread extends HandlerThread {
public EpicThread(String name) {
super(name);
}
}
The activity does not really do much either. I did this for some testing.
public class MainActivity extends Activity {
EpicThread et;
Looper l;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EpicThread et = new EpicThread("The epic thread");
et.start();
}
public void click(View v) {
l = et.getLooper();
Handler h = new Handler(l);
h.post(new Runnable() {
#Override
public void run() {
System.out.println("This is running on the epic thread");
}
});
}
}
So I test this by pressing the button, which gives me a InvocationTargetException when getLooper() is called:
E/AndroidRuntime(23262): FATAL EXCEPTION: main
E/AndroidRuntime(23262): java.lang.IllegalStateException: Could not execute method of the activity
E/AndroidRuntime(23262): at android.view.View$1.onClick(View.java:3660)
E/AndroidRuntime(23262): at android.view.View.performClick(View.java:4162)
E/AndroidRuntime(23262): at android.view.View$PerformClick.run(View.java:17088)
E/AndroidRuntime(23262): at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime(23262): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(23262): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(23262): at android.app.ActivityThread.main(ActivityThread.java:4867)
E/AndroidRuntime(23262): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23262): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23262): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
E/AndroidRuntime(23262): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
E/AndroidRuntime(23262): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(23262): Caused by: java.lang.reflect.InvocationTargetException
E/AndroidRuntime(23262): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(23262): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(23262): at android.view.View$1.onClick(View.java:3655)
E/AndroidRuntime(23262): ... 11 more
E/AndroidRuntime(23262): Caused by: java.lang.NullPointerException
E/AndroidRuntime(23262): at com.asdf.qwert.MainActivity.click(MainActivity.java:49)
E/AndroidRuntime(23262): ... 14 more
Fiddling a little with this code, I noticed that :
Getting the Looper with l = et.getLooper(); works right after creating the thread, after et.start();.
If I use HandlerThread directly instead of EpicThread, it works regardless of when getLooper() is called.
So I have no idea why this exception is thrown, and why simply by not using a subclass things started to work.

Converter application error on Android

Hello guys I am making an Android app that convert from binary to decimal and I have made a class called Binary and a class called Decimal and a function in the Binary class that convert from decimal to binary
public Binary DtoB(Decimal decimal)
{
String temp = null;
do
{
if(decimal.decimal%2!=0)
temp+='1';
else
temp+='0';
decimal.decimal/=2;
}while(decimal.decimal>0);
while(temp.length()%4!=0)
temp+='0';
for(int i=temp.length()-1;i>=0;i--)
{
this.bn+=temp.charAt(i);
}
return this;
}
and in the activity there's a button that converts, but when I test and press on the button the app breaks
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
d1.decimal=Integer.parseInt(e1.getText().toString());
b.DtoB(d1);
t1.setText(b.bn);
}
});
can any one help me please ???
Here is the logcat:
10-26 09:16:15.831: E/AndroidRuntime(280): FATAL EXCEPTION: main
10-26 09:16:15.831: E/AndroidRuntime(280): java.lang.NullPointerException
10-26 09:16:15.831: E/AndroidRuntime(280): at com.example.converter.MainActivity$1.onClick(MainActivity.java:34)
10-26 09:16:15.831: E/AndroidRuntime(280): at android.view.View.performClick(View.java:2408)
10-26 09:16:15.831: E/AndroidRuntime(280): at android.view.View$PerformClick.run(View.java:8816)
10-26 09:16:15.831: E/AndroidRuntime(280): at android.os.Handler.handleCallback(Handler.java:587)
10-26 09:16:15.831: E/AndroidRuntime(280): at android.os.Handler.dispatchMessage(Handler.java:92)
10-26 09:16:15.831: E/AndroidRuntime(280): at android.os.Looper.loop(Looper.java:123) 10-26 09:16:15.831: E/AndroidRuntime(280): at android.app.ActivityThread.main(ActivityThread.java:4627)
10-26 09:16:15.831: E/AndroidRuntime(280): at java.lang.reflect.Method.invokeNative(Native Method) 10-26 09:16:15.831: E/AndroidRuntime(280): at java.lang.reflect.Method.invoke(Method.java:521)
Try this...!
public class BinaryToDecimal {
public int getDecimalFromBinary(int binary){
int decimal = 0;
int power = 0;
while(true){
if(binary == 0){
break;
} else {
int tmp = binary%10;
decimal += tmp*Math.pow(2, power);
binary = binary/10;
power++;
}
}
return decimal;
}
public static void main(String a[]){
BinaryToDecimal bd = new BinaryToDecimal();
System.out.println("11 ===> "+bd.getDecimalFromBinary(11));
System.out.println("110 ===> "+bd.getDecimalFromBinary(110));
System.out.println("100110 ===> "+bd.getDecimalFromBinary(100110));
}
}
check variable all are initialize perfectly . because some time objectc are created but it is null so can't work and throw java.lang.NullPointerException .....
b1 , d1 , b ,t1

code with thread crashes at startup (android beginner)

I am trying to make an application that passes through the audio samples obtained at the microphone to the speaker. This is the source code:
public class MainActivity extends Activity {
AudioManager am = null;
AudioRecord record =null;
AudioTrack track =null;
final int SAMPLE_FREQUENCY = 44100;
final int SIZE_OF_RECORD_ARRAY = 1024;
boolean isPlaying = false;
class MyThread extends Thread{
#Override
public void run(){
recordAndPlay();
}
}
MyThread newThread;
private void init() {
int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, min);
int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
init();
newThread.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void recordAndPlay() {
short[] lin = new short[SIZE_OF_RECORD_ARRAY];
int num = 0;
am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION);
record.startRecording();
track.play();
while (true) {
num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
track.write(lin, 0, num);
}
}
public void passStop(View view){
Button playBtn = (Button) findViewById(R.id.playBtn);
// /*
if(!isPlaying){
record.startRecording();
track.play();
isPlaying = true;
playBtn.setText("Pause");
}
if(isPlaying){
record.stop();
track.pause();
isPlaying=false;
playBtn.setText("Pass through");
}
// */
}
#SuppressWarnings("deprecation")
#Override
public void onDestroy(){
newThread.stop();
}
}
Unfortunately, this program stops as soon as I try to run it through eclipse. This is wht I get in the logcat but I am not sure what it all means:
08-19 18:58:43.365: D/AndroidRuntime(27915): Shutting down VM
08-19 18:58:43.365: W/dalvikvm(27915): threadid=1: thread exiting with uncaught exception (group=0x4161f700)
08-19 18:58:43.365: E/AndroidRuntime(27915): FATAL EXCEPTION: main
08-19 18:58:43.365: E/AndroidRuntime(27915): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mypassthrough/com.example.mypassthrough.MainActivity}: java.lang.NullPointerException
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread.access$600(ActivityThread.java:141)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.os.Handler.dispatchMessage(Handler.java:99)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.os.Looper.loop(Looper.java:137)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread.main(ActivityThread.java:5103)
08-19 18:58:43.365: E/AndroidRuntime(27915): at java.lang.reflect.Method.invokeNative(Native Method)
08-19 18:58:43.365: E/AndroidRuntime(27915): at java.lang.reflect.Method.invoke(Method.java:525)
08-19 18:58:43.365: E/AndroidRuntime(27915): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
08-19 18:58:43.365: E/AndroidRuntime(27915): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-19 18:58:43.365: E/AndroidRuntime(27915): at dalvik.system.NativeStart.main(Native Method)
08-19 18:58:43.365: E/AndroidRuntime(27915): Caused by: java.lang.NullPointerException
08-19 18:58:43.365: E/AndroidRuntime(27915): at com.example.mypassthrough.MainActivity.onCreate(MainActivity.java:46)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.Activity.performCreate(Activity.java:5133)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
08-19 18:58:43.365: E/AndroidRuntime(27915): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
08-19 18:58:43.365: E/AndroidRuntime(27915): ... 11 more
What could be the reason for this code crashing, and how can it be debugged? I am pretty sure it has something to do with Thread, because my other versions of this code where I have not included Thread at all do not crash on startup.
Variable newThread is not initialized in oncreate() method that's why it is giving nullpointer exception
add this in your init() method it will work
newThread=new Thread();
You are getting a null pointer exception because newThread has not been initialized yet and it is null when you try to start it. The thread doesn't have anything to do also. You should look at implementing a runnable, handler, and timer into your activity instead of a thread.
Use sub class with extending AsyncTask Class
class TestActivity extends AsyncTask <String, Void, String > {
protected String doInBackground(String... urls) {
// execution
}
protected void onPostExecute(String result) {
// post execution
}
protected void onPreExecute() {
super.onPreExecute();
// initial activities
}
}

Media Player sample app crash

I am writing an app and When I try to load the class/layout by pressing a button on my main menu, I get the following logcat errors and I do not know what they mean, can anyone tell me why my app is crashing?
03-11 16:40:06.955: E/AndroidRuntime(18456): FATAL EXCEPTION: main
03-11 16:40:06.955: E/AndroidRuntime(18456): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.famouspeople/com.example.famouspeople.Music}: java.lang.InstantiationException: can't instantiate class com.example.famouspeople.Music; no empty constructor
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2024)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread.access$600(ActivityThread.java:140)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.os.Handler.dispatchMessage(Handler.java:99)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.os.Looper.loop(Looper.java:137)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread.main(ActivityThread.java:4898)
03-11 16:40:06.955: E/AndroidRuntime(18456): at java.lang.reflect.Method.invokeNative(Native Method)
03-11 16:40:06.955: E/AndroidRuntime(18456): at java.lang.reflect.Method.invoke(Method.java:511)
03-11 16:40:06.955: E/AndroidRuntime(18456): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
03-11 16:40:06.955: E/AndroidRuntime(18456): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
03-11 16:40:06.955: E/AndroidRuntime(18456): at dalvik.system.NativeStart.main(Native Method)
03-11 16:40:06.955: E/AndroidRuntime(18456): Caused by: java.lang.InstantiationException: can't instantiate class com.example.famouspeople.Music; no empty constructor
03-11 16:40:06.955: E/AndroidRuntime(18456): at java.lang.Class.newInstanceImpl(Native Method)
03-11 16:40:06.955: E/AndroidRuntime(18456): at java.lang.Class.newInstance(Class.java:1319)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.Instrumentation.newActivity(Instrumentation.java:1057)
03-11 16:40:06.955: E/AndroidRuntime(18456): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2015)
03-11 16:40:06.955: E/AndroidRuntime(18456): ... 11 more
03-11 16:40:16.560: I/Process(18456): Sending signal. PID: 18456 SIG: 9
Code:
public class Music implements OnCompletionListener{
MediaPlayer mediaPlayer;
boolean isPrepared = false;
public Music(AssetFileDescriptor assetDescriptor){
mediaPlayer = new MediaPlayer();
try{
mediaPlayer.setDataSource(assetDescriptor.getFileDescriptor(), assetDescriptor.getStartOffset(), assetDescriptor.getLength());
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch(Exception ex){
throw new RuntimeException("Couldn't load music, uh oh!");
}
}
public Music(FileDescriptor fileDescriptor){
mediaPlayer = new MediaPlayer();
try{
mediaPlayer.setDataSource(fileDescriptor);
mediaPlayer.prepare();
isPrepared = true;
mediaPlayer.setOnCompletionListener(this);
} catch(Exception ex){
throw new RuntimeException("Couldn't load music, uh oh!");
}
}
public void onCompletion(MediaPlayer mediaPlayer) {
synchronized(this){
isPrepared = false;
}
}
public void play() {
if(mediaPlayer.isPlaying()){
return;
}
try{
synchronized(this){
if(!isPrepared){
mediaPlayer.prepare();
}
mediaPlayer.start();
}
} catch(IllegalStateException ex){
ex.printStackTrace();
} catch(IOException ex){
ex.printStackTrace();
}
}
public void stop() {
mediaPlayer.stop();
synchronized(this){
isPrepared = false;
}
}
public void switchTracks(){
mediaPlayer.seekTo(0);
mediaPlayer.pause();
}
public void pause() {
mediaPlayer.pause();
}
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public boolean isLooping() {
return mediaPlayer.isLooping();
}
public void setLooping(boolean isLooping) {
mediaPlayer.setLooping(isLooping);
}
public void setVolume(float volumeLeft, float volumeRight) {
mediaPlayer.setVolume(volumeLeft, volumeRight);
}
public void dispose() {
if(mediaPlayer.isPlaying()){
stop();
}
mediaPlayer.release();
}
}
You need to define the no argument constructor otherwise the systems doesn't know how to instantiate it. Dalvik VM looking for a zero-argument constructor. If you define one argument or more than one in a service.
public Music() {
....
}
Android instrumentation is trying to create an instance of com.example.famouspeople.Music and for that it needs a default constructor. That is why it has failed. Creating a default constructor, public com.example.famouspeople.Music(){} in the Music class could help.
public class Music implements OnCompletionListener{
public Music ()
{
}
public boolean setFileDescriptor(FileDescriptor fileDescriptor){
//set file descriptor for the current instance
}
public boolean init(){
//do initialisation of player
}
}
call init() after setting file descriptor. But the whole naming conventions seems confusing for your package/classes.

Categories