我正在开发一个执行线程的Android应用程序,并通过GUI Activity上的GUI处理程序更新GUI。 当用户将应用程序放在后台时,我需要线程运行。这样就完成了!
我的问题是,当用户通过应用历史记录或应用启动器返回时,我想返回之前运行的Activity。 相反,许多人经常会启动一个新的Activity实例。
我尝试过使用应用程序属性“launchMode”(“SingleTop”,“SingleInstance”,“SingleTask”),但我无法实现目标。
另一种方法可能是我从每个运行线程的Activity打开一个通知,但是如何打开与该通知“链接”的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 :(得分:0)
我已经解决了!
问题是Back按钮破坏了活动。 然后我覆盖onBackPressed方法并询问用户是退出还是让活动继续运行。此外,我已经设置了 launchMode =“singleTop”。
比我想象的容易;)
但是我有一个疑问:应用程序如何在销毁之后运行?在按下后退按钮后也可以看到吐司。什么被摧毁呢?