2011-09-27 3 views
1

GUI 작업에 대한 GUI 처리기를 통해 스레드를 실행하고 GUI를 업데이트하는 Android 앱을 개발 중입니다. 사용자가 백그라운드에서 앱을 넣을 때도 스레드가 실행되어야합니다. 이건 끝났어!Android : 단일 (기본) Activity 인스턴스를 얻거나 필요한 Activity 인스턴스를 검색하는 방법은 무엇입니까?

내 문제는 이전에 실행 중이던 활동으로 돌아가고 싶다는 것입니다. 사용자가 앱 기록이나 앱 실행기로 돌아올 때 돌아가고 싶습니다. 대신 Android는 종종 새로운 활동 인스턴스를 시작합니다.

응용 프로그램 속성 "launchMode"("SingleTop", "SingleInstance", "SingleTask")로 시도했지만 목표를 얻을 수 없습니다.

다른 방법으로는 스레드를 실행하는 모든 활동으로부터 알림을 열 수 있지만 해당 알림에 "링크 된"활동을 열려면 어떻게해야합니까? 샘플 코드 나는 하나의 클래스에있는 모든 코드를 삽입 한 단순성 : 나는 당신의 도움이

에 희망

편집 감사드립니다.

이 응용 프로그램을 시도하면 하단의 버튼을 누르면 스레드가 시작됩니다. 이제 집에 가서 다른 앱을 열면 스레드가 다시 실행되고 있음을 알 수 있습니다. 내 앱에서 돌아 오거나 알림이나 런처 또는 앱을 클릭하면 토스트가 보입니다. 새로운 인스턴스를 생성 할 수 있으며 이전 실행을 잃어 버렸습니다. 어떻게 해결할 수 있습니까? 달리기 활동에 대해 언제 어떻게 돌아갈 수 있습니까?

TestThreadActivity.java

package tld.test; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.widget.ArrayAdapter; 
import android.widget.CompoundButton; 
import android.widget.CompoundButton.OnCheckedChangeListener; 
import android.widget.ListView; 
import android.widget.Toast; 
import android.widget.ToggleButton; 

public class TestThreadActivity extends Activity { 

    private static final int NOTIFY_THREAD_IS_RUNNING = 1; 
    private MyRunnable myRunnable; 
    private Thread myThread; 
    // List of all message 
    private ArrayList<String> responseList = new ArrayList<String>(10); 
    // ListView adapter 
    private ArrayAdapter<String> responseListAdapter; 

    /** 
    * Called when the activity is first created. 
    **/ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     responseListAdapter = new ArrayAdapter<String>(this, 
      R.layout.list_item, responseList); 
     ListView listViewResponse = (ListView) findViewById(R.id.listViewResponse); 
     listViewResponse.setAdapter(responseListAdapter); 
     ToggleButton toggleButton = (ToggleButton) findViewById(R.id.startStopBtn); 
     toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
       if (isChecked) 
        startThread(); 
       else 
        stopThread(); 
      } 
     }); 
    } 

    /** 
    * Create and start the thread 
    **/ 
    private void startThread() { 
     // Clear listview 
     responseList.clear(); 
     responseListAdapter.notifyDataSetChanged(); 
     if (myRunnable == null) 
     myRunnable = new MyRunnable(guiHandler); 
     myThread = new Thread(myRunnable, "myThread-" + System.currentTimeMillis()); 
     myThread.start(); 
     notifyThread(); 
     Toast.makeText(this, "Thread Started", Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * Stop the thread 
    **/ 
    private void stopThread() { 
     myRunnable.stop(); 
     cancelNotifyThread(); 
     Toast.makeText(this, "Thread Stopped", Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * Crea una notifica sulla barra di stato 
    */ 
    private void notifyThread() { 
     int icon = R.drawable.icon; // default icon from resources 
     CharSequence tickerText = "Thread is running"; // ticker-text  
     long when = System.currentTimeMillis(); // notification time 
     Context context = getApplicationContext(); // application Context 
     CharSequence contentTitle = getString(R.string.app_name); // expanded 
                   // message 
                   // title 
     CharSequence contentText = "Thread is running..."; // expanded message 
                  // text 
     Intent notificationIntent = new Intent(this, this.getClass()); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
      notificationIntent, 0); 
     // the next two lines initialize the Notification, using the 
     // configurations above 
     Notification notification = new Notification(icon, tickerText, when); 
     notification.flags |= Notification.FLAG_ONGOING_EVENT; 
     notification.setLatestEventInfo(context, contentTitle, contentText, 
      contentIntent); 
     NotificationManager notificationManager = ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)); 
     notificationManager.notify(NOTIFY_THREAD_IS_RUNNING, notification); 
    } 

    /** 
    * Clear previous notification 
    */ 
    private void cancelNotifyThread() { 
     NotificationManager notificationManager = ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)); 
     notificationManager.cancel(NOTIFY_THREAD_IS_RUNNING); 
    } 

    // My GUI Handler. Receive message from thread to put on Activity's listView 
    final private Handler guiHandler = new Handler() { 

     @Override 
     public void handleMessage(Message msg) { 
       String newMsg = (String) msg.obj; 
       // Add message to listView 
      responseList.add(newMsg); 
      responseListAdapter.notifyDataSetChanged(); 
       // and show a toast to view that is running also when it is not in 
      // foreground. 
      Toast.makeText(TestThreadActivity.this, newMsg, Toast.LENGTH_SHORT) 
       .show(); 
      super.handleMessage(msg); 
     } 
    }; 

    /** 
    * Simple runnable. Only wait WAIT_INTERVAL milliseconds and send a message 
    * to the GUI 
    **/ 
    public class MyRunnable implements Runnable { 
     public static final int WHAT_ID = 1; 
     private static final int WAIT_INTERVAL = 5000; 
     private boolean isRunning; 
     private int counter; 
     private Handler guiHandler; 

     public MyRunnable(Handler guiHandler) { 
      super(); 
      this.guiHandler = guiHandler; 
     } 

     public void stop() { 
      isRunning = false; 
     } 

     @Override 
     public void run() { 
      counter = 0; 
      isRunning = true; 
      while (isRunning) { 
       // Pause 
       try { 
        Thread.sleep(WAIT_INTERVAL); 
       } catch (InterruptedException e) { 
       } 
       // Notify GUI 
       Message msg = guiHandler.obtainMessage(WHAT_ID, 
        "Thread is running: " + (++counter) + " loop"); 
       guiHandler.sendMessage(msg); 
      } 
     } 
    } 
} 

레이아웃 \의 main.xml에 :

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ListView android:layout_width="match_parent" android:id="@+id/listViewResponse" 
     android:layout_height="0dip" android:layout_weight="1.0" android:transcriptMode="normal"></ListView> 
    <ToggleButton android:id="@+id/startStopBtn" 
     android:layout_height="wrap_content" android:layout_width="match_parent" android:textOn="@string/toggleBtnStop" android:textOff="@string/toggleBtnStart"></ToggleButton> 
</LinearLayout> 

레이아웃 \의 list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="10dp" 
    android:textSize="16sp" > 
</TextView> 

값 \ strings.xml의 :

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="app_name">TestThread</string> 
    <string name="toggleBtnStart">Start Thread</string> 
    <string name="toggleBtnStop">Stop Thread</string> 
</resources> 

답변

0

나는 해결했다!

문제는 활동을 파괴하는 뒤로 버튼이었습니다. 그렇다면 은 onBackPressed 메서드을 무시하고 사용자에게 종료 또는 활동 실행 여부를 묻습니다. 또한 launchMode = "singleTop"을 설정했습니다. 어떻게 파괴 후 실행되는 앱 수 : 생각보다 쉬웠다

)

그러나을 나는 의심의 여지가? 토스트는 뒤로 버튼을 누른 후에도 볼 수있었습니다. 그러면 무엇이 파괴됩니까?

관련 문제