Sensor를 Thread로 만들고 있는데, 잘 안됩니다.
제가 만드는 방식이 맞는건가요?
작동이 안되고, 강제 종료가 됩니다.
지금 5일째 밤낮으로 이 작업만 하는데,
Thread로 만드는 방법을 모르겠네요.
이것이 끝나야지 GPS도 Thread로 할 수 있을것 같은데.
어떻게 만드는지 좀 알려주실수 있나요?
main.java
public class main extends Activity {
/** Called when the activity is first created. */
int mMainValue = 0;
TextView mMainText;
TextView mBackText;
Button upbtn;
Thread mThread;
int mValue = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMainText = (TextView)findViewById(R.id.mainvalue);
mBackText = (TextView)findViewById(R.id.backvalue);
upbtn = (Button)findViewById(R.id.button1);
upbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mValue++;
mMainText.setText("MainValue:"+mValue);
}
});
mThread = new Thread((Runnable) mHandler);
mThread.setDaemon(true);
mThread.start();
}
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
mBackText.setText("BackValue : " + msg.arg1);
}
}
};
}
BackThread.java
public class BackThread extends Activity implements Runnable {
int mBackValue = 0;
Handler mHandler;
private Mysensor mShaker;
BackThread(Handler handler) {
mHandler = handler;
}
public void run() {
mShaker = new Mysensor(this);
while (true) {
mShaker.setOnShakeListener(new Mysensor.OnShakeListener() {
public void onShake()
{
// 흔드는 동작이 검출되면 1씩 증가시킨다.
mBackValue++;
}
});
Message msg = Message.obtain(mHandler, 0, mBackValue, 0);
mHandler.sendMessage(msg);
}
}
}
Mysensor.java
public class Mysensor implements SensorEventListener {
final static String TAG = "MotionCounter";
final static float G = SensorManager.STANDARD_GRAVITY;
SensorManager mSensorManager;
private Sensor mAccelerometer;
private OnShakeListener mShakeListener;
private Context mContext;
long mApplyTime;
int mSenGap = 1000;
float mSenRange = 16.0f;
int mSenSpeed = 800;
ArrayList<AccelValue> arValue = new ArrayList<AccelValue>();
final static int MAXCOUNT = 20;
class AccelValue {
float[] value = new float[3];
long time;
}
public Mysensor(Context context) {
mContext = context;
resume();
}
// ShakeListener 리스너
public interface OnShakeListener {
public void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
public void resume( ) {
// 가속기 센서 등록
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // !!! NEW !!!
boolean accelSupported = mSensorManager.registerListener(this,
mAccelerometer, // 가속도 센서
SensorManager.SENSOR_DELAY_GAME);
if (!accelSupported) {
mSensorManager.unregisterListener(this);
}
}
// 파괴되기 전까지 계속 동작해야 함
protected void pause() {
// 가속기 센서 등록 해제
if (mSensorManager != null) {
mSensorManager.unregisterListener(this);
mSensorManager = null;
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
// 가속값 큐 방식의 배열에 누적
AccelValue av = new AccelValue();
av.value[0] = event.values[0];
av.value[1] = event.values[1];
av.value[2] = event.values[2];
av.time = event.timestamp / 100000L;
if (arValue.size() == MAXCOUNT) {
arValue.remove(0);
}
arValue.add(av);
// 인식 간격이 지나지 않았으면 무시
long now = System.currentTimeMillis();
if (now - mApplyTime < mSenGap) {
break;
}
// 지정한 기간내에 각 방향 가속값의 최소, 최대값 및 진폭 계산
float[] min = new float[] { 100, 100, 100};
float[] max = new float[] { -100, -100, -100};
for (int i = arValue.size() - 1; i >= 0; i--) {
AccelValue v = arValue.get(i);
if (av.time - v.time > mSenSpeed) {
break;
}
for (int j = 0; j < 3; j++) {
min[j] = Math.min(min[j], v.value[j]);
max[j] = Math.max(max[j], v.value[j]);
}
}
float[] diff = new float[3];
for (int j = 0; j < 3; j++) {
diff[j] = Math.abs(max[j] - min[j]);
}
// X 축 흔들기 - 증가
if (diff[0] > mSenRange) {
mApplyTime = now;
if (mShakeListener != null) {
mShakeListener.onShake();
}
arValue.clear();
break;
}
// Y 축 흔들기 - 리셋
if (diff[1] > mSenRange) {
mApplyTime = now;
if (mShakeListener != null) {
mShakeListener.onShake();
}
arValue.clear();
break;
}
// Z 축 흔들기 - 감소
if (diff[2] > mSenRange) {
mApplyTime = now;
if (mShakeListener != null) {
mShakeListener.onShake();
}
arValue.clear();
break;
}
break;
}
}
float Deg2Rad(float deg) {
return (deg * (float)Math.PI) / 180;
}
}
백그라운드 스레드 생성시... while(true)로 shakeListener() 를 계속 생성할테니 뻗어 버리겠군요.
thread는 run()메소드가 종료되면 죽게됩니다. 그래서 deamon thread를 만들때 run() 메소드 내에 조건문으로 - while(true) 로 돌려서 계속 동작하게 만들게 되구요.
thread가 while(true)일 때 wait이나 sleep이 없으면 그 놈만 계속 돌아서 시분할로 돌 수 없겠죠. CPU가 한놈만 잡고 있으니까요.
보통 Activity가 뜨게 되면 해당 activity class의 코드가 돌아갈 때 메인UI thread가 해당 코드를 실행한다고 생각하시면 됩니다.
연산용 thread로 시간이 걸리는 연산을 처리하고, activity class 내에 handler에게 메세지를 던져주면, handler의 handleMessage 메소드는 메인UI thread에서 돌아간다고 생각하시면 간단할 겁니다.
전체적으로 thread와 handler의 사용의 잘못된것 같군요. API에 대해서 좀더 공부를 하셔야 할 것 같습니다...




mThread = new Thread(){
public void run(){
Message msg = Message.obtain(); // 재사용
msg.what = 0;
mHandler.sendMessage(msg);
}
};
제가 아는 방법으로 바꿨는데요,, 에러는 안나는데 맞는건지는 모르겟네요 -0-;