2012-06-18 126 views
-1

我有兩個活動以及一個Application類,每當我在其中一個活動中調用我的Application類時,程序崩潰。下面是的onCreate()方法的兩個活動:ClassCastException導致我的程序崩潰

的MainMenu:

protected BluetoothApplication myBt; 

private TextView bluetoothText; 
/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
    setContentView(R.layout.main); 

    myBt = ((BluetoothApplication)getApplicationContext()); 

    bluetoothText = new TextView(this); 

    customTitleBar(getText(R.string.app_name).toString(), bluetoothText.getText().toString()); 
} 

DEVICELIST:

protected BluetoothApplication myBt; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Setup the window 
    //requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
    setContentView(R.layout.device_list); 

    myBt = (BluetoothApplication)getApplicationContext(); 

    // Set result CANCELED in case the use backs out 
    //setResult(Activity.RESULT_CANCELED); 

    // Initialize the button to perform device discovery 
    Button scanButton = (Button) findViewById(R.id.button_scan); 
    scanButton.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      doDiscovery(); 
      v.setVisibility(View.GONE); 
     } 
    }); 

    // Initialize array adapters. One for already paired devices and one 
    // for newly discovered devices 
    mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 
    mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 

    // Find and set up the ListView for paired devices 
    ListView pairedListView = (ListView) findViewById(R.id.paired_devices); 
    pairedListView.setAdapter(mPairedDevicesArrayAdapter); 
    pairedListView.setOnItemClickListener(mDeviceClickListener); 

    // Find and set up the ListView for newly discovered devices 
    ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); 
    newDevicesListView.setAdapter(mNewDevicesArrayAdapter); 

    // Register for broadcasts when a device is discovered 
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
    this.registerReceiver(mReceiver, filter); 

    // Register for broadcasts when discovery has finished 
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
    this.registerReceiver(mReceiver, filter); 

    // Get a set of currently paired devices 
    Set<BluetoothDevice> pairedDevices = myBt.getMyBtAdapter().getBondedDevices(); 

    if(pairedDevices.size() > 0) { 
     findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); 
     for (BluetoothDevice device : pairedDevices) { 
      mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 
     } 
    } else { 
     String noDevices = getResources().getText(R.string.none_paired).toString(); 
     mPairedDevicesArrayAdapter.add(noDevices); 
    } 

} 

這些活動都加載很好,當我刪除涉及BluetoothApplication線。我已經嘗試將getApplicationContext()更改爲getApplication()。

BluetoothApplication:

public class BluetoothApplication extends Application { 
// Debugging 
private static final String TAG = "BluetoothApplication"; 
private static final boolean D = true; 

// Member fields 
private BluetoothAdapter myAdapter; 
private Handler myHandler; 
private BluetoothDevice myBtDevice; 
private BluetoothSocket mySocket; 
private ArrayAdapter<String> mPairedDevicesArrayAdapter; 
private ArrayAdapter<String> mNewDevicesArrayAdapter; 
private ConnectThread myConnectThread; 
private ConnectedThread myConnectedThread; 
private int myState; 


// Constants that indicate the current connection state 
public static final int STATE_NONE = 0; 
public static final int STATE_LISTEN = 1; 
public static final int STATE_CONNECTING = 2; 
public static final int STATE_CONNECTED = 3; 


//In SDK15 (4.0.3) this method is now public as 
//Bluetooth.fetchUuisWithSdp() and BluetoothDevice.getUuids() 
public ParcelUuid[] servicesFromDevice(BluetoothDevice device) { 
    try { 
     Class cl = Class.forName("android.bluetooth.BluetoothDevice"); 
     Class[] par = {}; 
     Method method = cl.getMethod("getUuids", par); 
     Object[] args = {}; 
     ParcelUuid[] retval = (ParcelUuid[]) method.invoke(device, args); 
     return retval; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 



public void onCreate() { 
    myAdapter = BluetoothAdapter.getDefaultAdapter(); 
    myAdapter.enable(); 

} 


public BluetoothAdapter getMyBtAdapter() { 
    return myAdapter; 
} 

/** 
* Set the connection state of the device. 
* @param state 
*/ 
public synchronized void setState(int state) { 
    if(D) Log.d(TAG, " setState() " + myState + " -> " + state); 
    myState = state; 

    myHandler.obtainMessage(MainMenu.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

/** 
* Get the connection state. 
*/ 
public synchronized int getState() { 
    return myState; 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
private void connectionFailed() { 
    setState(STATE_NONE); 

    // Send failure message back to the Activity 
    Message msg = myHandler.obtainMessage(MainMenu.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(" ", "unable to connect to device"); 
    msg.setData(bundle); 
    myHandler.sendMessage(msg); 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
private void connectionLost() { 
    setState(STATE_NONE); 

    Message msg = myHandler.obtainMessage(MainMenu.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString("ASdasd", "Device connection was lost"); 
    msg.setData(bundle); 
    myHandler.sendMessage(msg); 
} 

public synchronized void start() { 
    if (D) Log.d(TAG, "start"); 

    if(myConnectThread != null) { 
     myConnectThread.cancel(); 
     myConnectThread = null; 
    } 

    if(myConnectedThread != null) { 
     myConnectedThread.cancel(); 
     myConnectedThread = null; 
    } 

    setState(STATE_NONE); 
} 

public synchronized void connect(BluetoothDevice device) { 
    if(D) Log.d(TAG, "connect to: " + device); 

    if(myState == STATE_CONNECTING) { 
     if(myConnectThread != null) { myConnectThread.cancel(); myConnectThread = null;} 
    } 

    // Cancel any thread currently running a connection 
    if(myConnectedThread != null) {myConnectedThread.cancel(); myConnectedThread = null;} 

    // Start the thread to connect with the given device 
    myConnectThread = new ConnectThread(device); 
    myConnectThread.start(); 
    setState(STATE_CONNECTING); 
} 

/** 
* Start the ConnectedThread to begin managin a Bluetooth connection 
*/ 
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
    if(D) Log.d(TAG, "connected"); 

    // Cancel the thread that completed the connection 
    if(myConnectThread != null) { 
     myConnectThread.cancel(); 
     myConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if(myConnectedThread != null) { 
     myConnectedThread.cancel(); 
     myConnectedThread = null; 
    } 

    // Start the thread to manage the connection and perform transmissions 
    myConnectedThread = new ConnectedThread(socket); 
    myConnectedThread.start(); 

    // Send the name of the connected device back to the UI Activity 
    Message msg = myHandler.obtainMessage(MainMenu.MESSAGE_DEVICE_NAME); 
    Bundle bundle = new Bundle(); 
    bundle.putString(MainMenu.DEVICE_NAME, device.getName()); 
    msg.setData(bundle); 
    myHandler.sendMessage(msg); 

    setState(STATE_CONNECTED); 
} 

/** 
* Stop ALL threads 
*/ 

public synchronized void stop() { 
    if(D) Log.d(TAG, "stop"); 

    if(myConnectThread != null) { 
     myConnectThread.cancel(); 
     myConnectThread = null; 
    } 

    if(myConnectedThread != null) { 
     myConnectedThread.cancel(); 
     myConnectedThread = null; 
    } 

    setState(STATE_NONE); 
} 

/** 
* Write to the ConnectedThread in an unsynchronized manner 
*/ 
public void write(byte[] out) { 
    ConnectedThread r; 
    synchronized(this) { 
     if(myState != STATE_CONNECTED) return; 
     r = myConnectedThread; 
    } 
    r.write(out); 
} 

public class ConnectThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 

    public ConnectThread(BluetoothDevice device) { 
     mmDevice = device; 
     BluetoothSocket tmp = null; 

     ParcelUuid[] uuids = servicesFromDevice(myBtDevice); 

     try { 
      tmp = device.createRfcommSocketToServiceRecord(uuids[0].getUuid()); 
     } catch (IOException e) { 
      Log.e(TAG, "create() failed", e); 
     } 
     mmSocket = tmp; 
    } 

    public void run() { 
     Log.i(TAG, "BEGIN mConnectThread"); 
     setName("ConnectThread"); 

     // Always cancel discovery because it will slow down a connection 
     myAdapter.cancelDiscovery(); 

     try { 
      mmSocket.connect(); 
     } catch (IOException e) { 
      connectionFailed(); 
      try { 
       mmSocket.close(); 
      } catch (IOException e2) { 
       Log.e(TAG, "Unable to close() socket during connection failure", e2); 
      } 
      BluetoothApplication.this.start(); 
      return; 
     } 

     synchronized (BluetoothApplication.this) { 
      myConnectThread = null; 
     } 

     connected(mmSocket, mmDevice); 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 
} 


/** 
* This thread runs during a connection with a remote device. 
* It handles all incoming and outgoing transmissions. 
*/ 
public class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 

    public ConnectedThread(BluetoothSocket socket) { 
     Log.d(TAG, "create ConnectedThread"); 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the BluetoothSocket input and output streams 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(TAG, "temp sockets not created", e); 
     } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
    } 

    public void run() { 
     Log.i(TAG, "BEGIN mConnectedThread"); 
     byte[] buffer = new byte[1024]; 
     int bytes; 

     while(true){ 
      try { 
       bytes = mmInStream.read(buffer); 
       myHandler.obtainMessage(MainMenu.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); 
      } catch (IOException e) { 
       Log.e(TAG, "disconnected", e); 
       connectionLost(); 
       break; 
      } 
     } 
    } 

    /** 
    * Write to connected OutStream. 
    * 
    */ 
    public void write(byte[] buffer) { 
     try { 
      mmOutStream.write(buffer); 
      myHandler.obtainMessage(MainMenu.MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget(); 
     } catch (IOException e) { 
       Log.e(TAG, "Exception during write", e); 
     } 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 

    } 
} 
} 

我也覺得有可能是壞了我如何進入應用類到我的清單文件:

改進清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="my.eti.commander" 
android:versionCode="1" 
android:versionName="1.0" > 

<uses-sdk android:minSdkVersion="10" /> 

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name = ".BluetoothApplication" > 
    <activity 
     android:name=".MainMenu" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity android:name=".DeviceList" 
       android:theme="@android:style/Theme.Dialog" 
       android:label="@string/devices"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
     </intent-filter> 
    </activity> 
</application> 

</manifest> 

這是LogCat:

06-18 09:09:26.625: I/Process(2097): Sending signal. PID: 2097 SIG: 9 
06-18 09:17:32.241: D/AndroidRuntime(2304): Shutting down VM 
06-18 09:17:32.241: W/dalvikvm(2304): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
06-18 09:17:32.241: E/AndroidRuntime(2304): FATAL EXCEPTION: main 
06-18 09:17:32.241: E/AndroidRuntime(2304): java.lang.RuntimeException: Unable to start activity ComponentInfo{my.eti.commander/my.eti.commander.MainMenu}: java.lang.ClassCastException: android.app.Application 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.os.Handler.dispatchMessage(Handler.java:99) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.os.Looper.loop(Looper.java:130) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at java.lang.reflect.Method.invokeNative(Native Method) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at java.lang.reflect.Method.invoke(Method.java:507) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at dalvik.system.NativeStart.main(Native Method) 
06-18 09:17:32.241: E/AndroidRuntime(2304): Caused by: java.lang.ClassCastException: android.app.Application 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at my.eti.commander.MainMenu.onCreate(MainMenu.java:47) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 
06-18 09:17:32.241: E/AndroidRuntime(2304):  ... 11 more 
+1

它會更容易找到錯誤,如果您發佈的堆棧跟蹤,而不是 – Kshitij

+1

發佈您的修改清單文件。 – user370305

+1

現在,你的代碼看起來很好,只是一個假設,把應用程序標籤中的完整應用程序名稱放在manifest標籤中,例如my.eti.commander.BluetoothApplication並嘗試它。 – user370305

回答

1

你忘了你的清單文件給應用程序的名稱。還有一些在你的清單文件中的兩個應用程序標籤,(刪除第二個)

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name=".BluetoothApplication" 
> 

,並刪除最後一個應用程序節點,

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name="BluetoothApplication"> 
</application> 
1

問題可能在於,您的活動是在不同的應用程序中聲明的,而不是Bluetooth應用程序。現在的方式是,活動的應用程序不聲明隱式類,因此使用默認的Application類。然後,您嘗試將其轉換爲藍牙應用程序中的活動,但事實並非如此。

嘗試擺脫清單中的第二個應用程序標記,並將android:name =「BluetoothApplication」添加到第一個應用程序標記。

+0

是的,這是有道理的,修復它,但它仍然崩潰 – JuiCe

+1

那麼,什麼是錯誤消息/堆棧跟蹤? – henrik

+0

剛剛添加到我原來的帖子,並更新我的清單文件 – JuiCe

1
<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 

您應該添加在這裏

android:name=".BluetoothApplication" 

使OS知道你有你自己的應用程序類。 此外,刪除此塊:

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:name="BluetoothApplication"> 
</application> 
+0

謝謝,修復,但它仍然崩潰 – JuiCe

+1

張貼堆棧跟蹤,請。 –