如何从Android应用程序中的主线程以外的线程启动新活动?

时间:2014-04-13 07:19:36

标签: android multithreading android-activity

我正在开发一款可以通过蓝牙播放的安卓游戏。我能够配对设备并完成插座。但这就是问题出现的地方。建立连接并且套接字 null后,我想在服务器和客户端设备上启动活动。我尝试过各种各样的东西但似乎没什么用。我是Android编程的新手,真的需要你的帮助。

这是我的 ServerThread.java

class ServerThread extends Thread {

private final BluetoothServerSocket mmServerSocket;
BluetoothAdapter mBluetoothAdapter;// = BluetoothAdapter.getDefaultAdapter();
final String NAME = "order and chaos";
final UUID MY_UUID = UUID.fromString("05c0bd24-c242-11e3-b4b6-b6ee55aeb395");
Context context;
public ServerThread(BluetoothAdapter mBluetoothAdapter,Context context) {
    // Use a temporary object that is later assigned to mmServerSocket,
    // because mmServerSocket is final
    this.context = context;
    this.mBluetoothAdapter = mBluetoothAdapter;
    BluetoothServerSocket tmp = null;
    try {
        // MY_UUID is the app's UUID string, also used by the client code
        tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
    } catch (IOException e) { }
    mmServerSocket = tmp;
}

public void run() {
    BluetoothSocket socket = null;
    // Keep listening until exception occurs or a socket is returned
    while (true) {
        try {
            socket = mmServerSocket.accept();
        } catch (IOException e) {
            break;
        }
        // If a connection was accepted
        if (socket != null) {
            // Do work to manage the connection (in a separate thread)



        }
    }

}

/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
    try {
        mmServerSocket.close();
    } catch (IOException e) { }
}
}

这是我的 ClientThread.java

public class ClientThread extends Thread
{

 private final BluetoothSocket mmSocket;
 private final BluetoothDevice mmDevice;
 BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 final UUID MY_UUID = UUID.fromString("05c0bd24-c242-11e3-b4b6-b6ee55aeb395");
 Context context;
    public ClientThread(BluetoothDevice device,BluetoothAdapter mBluetoothAdapter,Context context) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        this.context = context;
        this.mBluetoothAdapter = mBluetoothAdapter;
        BluetoothSocket tmp = null;
        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        ConnectedSocket con = new ConnectedSocket();
        con.start(1);
    }

    // Will cancel an in-progress connection, and close the socket 
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
 }

这是 ConnectedSocket.java 类导致错误

 public class ConnectedSocket extends Thread{

GameActivity gt = new GameActivity();
private Looper myLooper;
int side;
public void start(int i)
{
    side = i;
}
public void run()
{
    Looper.prepare();

    // code that needed a separated thread
    if(side==0)
        gt.serverSide();
    if(side==1)
     gt.clientSide();

    myLooper = Looper.myLooper();
    Looper.loop();
    myLooper.quit(); 
}}

class GameActivity extends Activity{

public void serverSide()
{
    Intent i = new Intent(this,SetBoard.class);
    startActivity(i);
    Toast toast = Toast.makeText(getApplicationContext(),"You are order", Toast.LENGTH_LONG);
    toast.setGravity(Gravity.TOP|Gravity.LEFT, 50, 50);
    toast.show();
}

public void clientSide()
{
    Intent i = new Intent(this, SetBoard.class);
    startActivity(i);
    Toast toast = Toast.makeText(getApplicationContext(),"You are chaos", Toast.LENGTH_LONG);
    toast.setGravity(Gravity.TOP|Gravity.LEFT, 50, 50);
    toast.show();
}
 }

这些错误我正在

04-13 12:39:36.680: E/AndroidRuntime(30346): FATAL EXCEPTION: Thread-12
04-13 12:39:36.680: E/AndroidRuntime(30346): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-13 12:39:36.680: E/AndroidRuntime(30346):    at android.os.Handler.<init>(Handler.java:121)
04-13 12:39:36.680: E/AndroidRuntime(30346):    at android.app.Activity.<init>(Activity.java:686)
04-13 12:39:36.680: E/AndroidRuntime(30346):    at com.chirag.sudoku.GameActivity.<init>(ConnectedSocket.java:34)
04-13 12:39:36.680: E/AndroidRuntime(30346):    at com.chirag.sudoku.ConnectedSocket.<init>(ConnectedSocket.java:11)        
04-13 12:39:36.680: E/AndroidRuntime(30346):    at com.chirag.sudoku.ClientThread.run(ClientThread.java:53)     
04-13 12:39:36.740: D/dalvikvm(30346): GC_CONCURRENT freed 217K, 47% free 2971K/5575K, external 3501K/4547K, paused 4ms+3ms         
04-13 12:39:46.790: E/ActivityThread(30346): Activity com.chirag.sudoku.BluetoothMode has leaked IntentReceiver com.chirag.sudoku.BluetoothMode$1@4054b6c0 that was originally registered here. Are you missing a call to unregisterReceiver()?
04-13 12:39:46.790: E/ActivityThread(30346): android.app.IntentReceiverLeaked: Activity com.chirag.sudoku.BluetoothMode has leaked IntentReceiver com.chirag.sudoku.BluetoothMode$1@4054b6c0 that was originally registered here. Are you missing a call to unregisterReceiver()?
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:756)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:551)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:871)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.ContextImpl.registerReceiver(ContextImpl.java:858)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.ContextImpl.registerReceiver(ContextImpl.java:852)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
04-13 12:39:46.790: E/ActivityThread(30346):    at com.chirag.sudoku.BluetoothMode.find(BluetoothMode.java:142)
04-13 12:39:46.790: E/ActivityThread(30346):    at java.lang.reflect.Method.invokeNative(Native Method)
04-13 12:39:46.790: E/ActivityThread(30346):    at java.lang.reflect.Method.invoke(Method.java:507)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.view.View$1.onClick(View.java:2180)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.view.View.performClick(View.java:2585)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.view.View$PerformClick.run(View.java:9299)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.os.Handler.handleCallback(Handler.java:587)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.os.Handler.dispatchMessage(Handler.java:92)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.os.Looper.loop(Looper.java:130)
04-13 12:39:46.790: E/ActivityThread(30346):    at android.app.ActivityThread.main(ActivityThread.java:3770)
04-13 12:39:46.790: E/ActivityThread(30346):    at java.lang.reflect.Method.invokeNative(Native Method)
04-13 12:39:46.790: E/ActivityThread(30346):    at java.lang.reflect.Method.invoke(Method.java:507)
04-13 12:39:46.790: E/ActivityThread(30346):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
04-13 12:39:46.790: E/ActivityThread(30346):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
04-13 12:39:46.790: E/ActivityThread(30346):    at dalvik.system.NativeStart.main(Native Method)

请告诉我如何解决它。 我甚至尝试通过ConnectedSocket类扩展Activity类来直接启动活动。但这会产生同样的错误。

2 个答案:

答案 0 :(得分:1)

这可能有用: -

Handler handler = new Handler();
Runnable run= new Runnable() {

    @Override
    public void run() {

           Intent in = new Intent(context, YourActivity.class);
           in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
           startActivity(in);

    }
};
handler.post(run);

答案 1 :(得分:0)

在你的线程中,你把当前类的上下文:

Intent in = new Intent(CurrentActivity.this, YourActivity.class);
startActivity(in);

或者您也可以将参数作为参数...