【问题标题】:Android: How to have a single (main) Activity instance or retrieve the Activity instance that I need?Android:如何拥有一个(主)Activity 实例或检索我需要的 Activity 实例?
【发布时间】:2011-09-27 15:42:59
【问题描述】:

我正在开发一个 Android 应用程序,它执行一个线程并通过 GUI Activity 上的 GUI 处理程序更新 GUI。 当用户将应用程序置于后台时,我需要线程也运行。完成了!

我的问题是,当用户通过应用历史记录或应用启动器返回之前运行的 Activity 时,我想返回它。 相反,许多 Android 通常会启动一个新的 Activity 实例。

我已尝试使用应用程序属性“launchMode”(“SingleTop”、“SingleInstance”、“SingleTask”),但无法实现目标。

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

希望得到你的帮助

谢谢

编辑:示例代码 为简单起见,我将所有代码放在一个类中。

如果您尝试使用此应用,请按底部的按钮,然后线程开始。现在,如果您回家打开其他应用程序,您可以看到线程再次运行,您会看到 toast(这就是我想要的),然后如果您返回我的应用程序,或者通过单击通知或通过启动器或通过应用程序历史,可以创建一个新实例,但我失去了以前的运行。 我该如何解决这个问题?如何始终返回跑步活动?

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>

【问题讨论】:

    标签: android multithreading android-activity instance


    【解决方案1】:

    我已经解决了!

    问题是破坏活动的后退按钮。 然后我 覆盖 onBackPressed 方法 并询问用户是退出还是让活动继续运行。此外,我设置了 launchMode="singleTop" 这就是我所需要的。

    这比我想象的要容易;)

    但是我有一个疑问:应用程序销毁后如何运行?按下后退按钮后,吐司也可见。那么销毁什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      相关资源
      最近更新 更多