2011-09-27 40 views
1

我正在开发一个Android应用程序,它执行线程并通过GUI活动上的GUI处理程序更新GUI。 我需要的线程也运行时,用户把应用程序在后台。这个做完了!Android:如何拥有一个(主要)Activity实例或检索我需要的Activity实例?

我的问题是,我想返回到用户通过应用程序历史记录或应用程序启动器返回之前运行的活动。 相反,很多时候Android会启动一个新的Activity实例。我尝试过应用程序属性“launchMode”(“SingleTop”,“SingleInstance”,“SingleTask”),但我无法获得我的目标。

另一种方法是,我可以从每个运行线程的Activity打开一个通知,但我该如何打开“链接到”该通知的活动?

我希望在您的帮助下

谢谢

编辑:示例代码 为了简单起见,我已经把所有的代码在一个单独的类。

如果你尝试这个应用程序,按下底部的按钮,并开始线程。现在,如果您回家打开其他应用程序,您可以看到线程正在运行,您会看到敬酒(这是我想要的),然后如果您返回我的应用程序,或者通过点击通知或启动程序或应用程序历史,可以创建一个新的实例,我失去了以前的运行。 我该如何解决这个问题?我如何在运行活动中始终返回?

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”这就是我需要的。

这比我想象的要简单;)

我有一个疑问:怎样才能应用程式后,破坏运行?在按下后退按钮后,吐司也可见。那么被破坏的是什么?

相关问题