Start a thread inside another thread - android

INTRODUCTION
I have a sub-class inside my main activity's class, which extends thread and is started every time the camera detectecs movement.
Inside this thread, when it dectects movement continuosly, it must start another thread which belongs to the main Activity's class.
I now it can be a bit messy but i'l explain it now in detail
CODE
This is a simplified version of my code that shows exactly what I mean:
public class MainActivity extends Activity {
//...
public Runnable SpeechWhenMotion = new Runnable() {
#Override
public void run() {
// Do stuff here
}
}
private static final class DetectionThread extends Thread {
//...
#Override
public void run() {
//...
//START "SpeechWhenMotion" HERE!
}
}
}
QUESTION
So the doubt I have is, how do I start the Runnable inside the thread of the DetectionThread class?
I've tryed using a handler but I think I'm not doing it right cause it doesn't get started.

If you really need SpeechWhenMotion runnable to be nester class of MainActivity you need to provide link of MainActivity or SpeechWhenMotion instance to DetectionThread class:
private static final class DetectionThread extends Thread {
private Runnable mSpeechWhenMotionRunnable;
//...
}
then, when you create DetectionThread assign SpeechWhenMotion to it from main activity
DetectionThread detectionThread = new DetectionThread();
detectionThread.mSpeechWhenMotionRunnable = SpeechWhenMotion;
And finally, call start new thread inside DetectionThread:
//START "SpeechWhenMotion" HERE!
new Thread(mSpeechWhenMotionRunnable).start();

I tried it out and this works rather smoothly:
new Thread(SpeechWhenMotion).start();

Related

Situation when a memory leak happens Android

I want to understand when a memory leak happens. For instance if i run this runnable in the activity, all the activity's context will be capture and if a rotation happens, the activity wont get released until the runnable terminates.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
executors.diskIO().execute(new Runnable() {
#Override
public void run() {
//CODE HERE
});
}
});
}
}
Lets say i put the runnable inside a class in a seperate file not within the MainActivity and initiate it from the activity. When a rotation happens, is there a memory leak in this case?. I mean the runnable captures the data in every rotation right?
public class A{
Data ....
public A() {}
functionB(){
executors.diskIO().execute(new Runnable() {
#Override
public void run() { }
});
});
}
}
Whenever you make an innerclass, it retains the reference of the outer class. If your runnable is inside an activity it will retain an instance to the activity and hence will result in memory leak whereas if you put it in class A it will hold reference of class A not of your activity
If you don't want to access members of the enclosing class it is preferable to make your class static as it wont hold the object of enclosing class.

Pass value from thread to main activity

I've been searching this online for a long time. Maybe what I'm doing here is wrong.
I have written a thread class in a separate file from MainActivity.java. Because both the thread and the main activity are relatively long, I decided to separate them into different files.
I wanted to pass some value generated from the thread class to the main activity. Initially I want to use handlers. But because the thread is in a different class to the main activity. It has no idea the handler I defined in the main activity.
public class mythread implements Runnable{
#Override
public void run(){
result = result_from_some_task();
}
}
This is the basic structure of my thread class and I want to pass result back to the main activity. I've looked at many examples, most of them the thread is within the main activity class and the handlers defined can be easily referred to.
Intent doesn't seems to be applicable. Does anyone have any idea on how such operations can be done?
Thanks in advance.
Make parameterized constructor of AnotherClass and when you make of object of AnotherClass then simply pass object of MainActivity into that constructor and inside AnotherClass class where you want to call MainActivity's method then simply call that method from that Object.
check following code :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AnotherClass object= new AnotherClass (this);
object.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;
}
public void makeSomeCalculation() {
//logic to change some UI
}
}
and check Another class :
public class AnotherClass extends Thread {
MainActivity mainActivity;
public AnotherClass (MainActivity mainActivity) {
// TODO Auto-generated constructor stub
this.mainActivity = mainActivity;
}
public void run() {
//write other logic
mainActivity.makeSomeCalculation();
//write other logic
}
}
This may not be what you are looking for so consider it as suggestion to avoid long term headaches.Try EventBus. This a library to communicate easily between various components in Android.
you need a handler in your activity. and when your thread finishes , you then dispatch a message to handler , notifying that thread execution finished. see here for example.
you can also use interface for this. see here for example. In answer, he use interface to notify from asyntask. you can do same for thread.
Your need to run the activity function within runOnUiThread.
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mainActivity.makeSomeCalculation();
}
});

Android make a dialogbox from an non ui-activity class

I don't need the code for the creation Dialog box on an activity.
I use opengles and i am drawing with the renderer class i create . I think the execution at the android activity window stays at main activity.
I have states of my drawing and when a draw reach a state i want to post a dialog box. So there is a problem with that because the dialogbox builder wants a context and the renderer class isnt an activity object.
I am new at opengles and firstly all the work i do exists at
method
public void onDrawFrame(GL10 gl)
{ }
so i have 2 classes 1st the ui class
mainactivity extends activity
and second the renderer class
class mainrenderer implements GLSurfaceView.Renderer
i want from the second class to use activity operations such as create dialog box .
Can you give me a solution to this ?
Thanks.
In other words i want from a class (renderer) that isn't ui class to make a dialogbox .
edited
i pass the context of my activity class
as myrender = new Renderer1(this);
at constructor of Renderer i have
class Renderer1 implements GLSurfaceView.Renderer
/* initializations */
public Renderer(Context context) {
super();
mcontext = context;
}
and after that i have implement the on drawFrame method and when i reach a state i call the method alertdialogbox()
given below
public void alertdialogbox() /* some code */ AlertDialog.Builder
builder = new AlertDialog.Builder(mcontext);
but it keeps erroring and application crashes when reach the state that the alertdialogbox called
the error begins with
java.lang.RuntimeException : Can't create handler inside thread that
has not called Looper.prepare()
Edit 2 solved
i initialize a handler at main activity as :
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
alertdialogbox();
}
};
alertdialogbox is a method that i declare inside main activity class
and constructs the dialogbox
again inside the main activity where i instantiate the GlsurfaceView and the Glrenderer
i pass the handler that i initialize before so :
Renderer = new Renderer1(handler);
after that at the class Renderer1
class Renderer1 implements GLSurfaceView.Renderer
Handler mhandler;
public Renderer( Handler handler) {
super();
mhandler = handler;
}
*
*
public void onDrawFrame(){
*
*
if (state)
{
alertdialogbox();
}
}
*
*
public void alertdialogbox()
{
mhandler.sendEmptyMessage(1);
}
and finally i have my dialogbox viewed.
thanks for the suggetions .
When creating a AlertDialog (or any other UI widget) from another class, you must have a reference to your activity class and with that object, you can call activity.runOnUIThread() to execute any code related to your AlertDialog.

android threading with activity;

In my activity class i created a obj from other java file in the same package , now that the work is finished in runnable , how do i come back to my activity class from where the thread was started.
consider this situation;
public class myActivity extends activity {
MyThread t;
public void onCreate(Bundle savedInstanceState) {
t = new Mythread();
t.start();
}
}
now t is simple java class which does some background checking of data , but I dont know how to come from this t.run() method to my activity so that I can jump to another activity from there.any help is appreciated.I am new to this scenario.Thanks in advance.
Regards,
Rohit
You should consider using an AsyncTask for this.
Put in onBackground() what needs to be done in the background and in onPostExecute() what needs modify the UI.

How to start an activity from a thread class in android?

I am extending a thread class and from that class I want to start an activity. How to do this?
You need to call startActivity() on the application's main thread. One way to do that is by doing the following:
Initialize a Handler and associate it with the application's main thread.
Handler handler = new Handler(Looper.getMainLooper());
Wrap the code that will start the Activity inside an anonymous Runnable class and pass it to the Handler#post(Runnable) method.
handler.post(new Runnable() {
#Override
public void run() {
Intent intent = new Intent (MyActivity.this, NextActivity.class);
startActivity(intent);
}
});
you can use Something like this.
public class MyActivity extends Activity
{
Handler hander = new Handler(){
public void handleMessage(Message m){
Intent intent = new Intent (MyActivity.this, Next.class);
startActivity(intent);
}
};
pubilc void onCreate(Bundle ic)
{
//your code setContentView() etc....
Thread toRun = new Thread()
{
public void run()
{
hander.sendMessage(1);
}
}
toRun.start();
}
}
Well to start an activity of an class, a class should extends with activity according to me.
But if you want to start activity with some threading function you can do these things.
Instead of extends Thread, use implements Runnable. After that some class that have an Activity you just call the start thread and put your logic and that start Intent.
I think this is the good solution for you.

Categories

Resources