【问题标题】:setOnItemSelectedListener makes my app crashsetOnItemSelectedListener 使我的应用程序崩溃
【发布时间】:2015-03-26 03:44:35
【问题描述】:

我正在尝试使用 Spinner 选择用户名,然后在客户端单击开始聊天按钮时打开新的对话布局。我确信按钮代码是正确的,但我的微调器导致我的应用程序崩溃。

myListView.setOnItemSelectedListener(new OnItemSelectedListener () {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, 
                               int pos, long id) {
        // An item was selected. You can retrieve the selected item using
        name1 = parent.getItemAtPosition(pos).toString();   
        CStart = (Button) findViewById(R.id.Start) ;
        CStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                open(v);
            }
        });
    }
    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
        }
    });

打开方法:

protected void open(View v) {
    Intent i = new Intent(this, MainActivity2.class);
    i.putExtra("message", name1);
    startActivityForResult(i, 1);
}

你能帮我修复我的代码吗?

日志猫:

03-24 19:48:32.967: E/AndroidRuntime(23058): FATAL EXCEPTION: main 
03-24 19:48:32.967: E/AndroidRuntime(23058): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.javachat/com.example.javachat.MainActivity}: java.lang.IllegalArgumentException: Receiver not registered: com.example.javachat.MainActivity$1@418afa30 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2343) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2395) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread.access$600(ActivityThread.java:162) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.os.Handler.dispatchMessage(Handler.java:107) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.os.Looper.loop(Looper.java:194) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread.main(ActivityThread.java:5371) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at java.lang.reflect.Method.invokeNative(Native Method) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at java.lang.reflect.Method.invoke(Method.java:525) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 03-24 19:48:32.967: E/AndroidRuntime(23058):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at dalvik.system.NativeStart.main(Native Method) 
03-24 19:48:32.967: E/AndroidRuntime(23058): Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.example.javachat.MainActivity$1@418afa30 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:657)
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1442) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:445) 03-24 19:48:32.967: E/AndroidRuntime(23058):  at com.example.javachat.MainActivity.onDestroy(MainActivity.java:229) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at com.example.javachat.MainActivity.onCreate(MainActivity.java:136) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.Activity.performCreate(Activity.java:5122) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1084) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307) 
03-24 19:48:32.967: E/AndroidRuntime(23058):... 11 more

清单代码:

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

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >



        <activity
            android:name=".MainActivity"
            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=".MainActivity2" />

    </application>

</manifest>

我的 .java 文件,如果您需要检查任何其他内容,例如导入和方法......

package com.example.javachat;

import java.util.Set;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
   private static final int REQUEST_ENABLE_BT = 1;
   private Button onBtn;
   private Button offBtn;
   private Button listBtn;
   private Button findBtn;
   private TextView text;
   private Button CStart ;
   private String name1 ;
   private BluetoothAdapter myBluetoothAdapter;
   private Set<BluetoothDevice> pairedDevices;
   private Spinner myListView;
   private ArrayAdapter<String> BTArrayAdapter;

  //*******************************MAIN************************
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main2);

      // take an instance of BluetoothAdapter - Bluetooth radio
      myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
      if(myBluetoothAdapter == null) {
          onBtn.setEnabled(false);
          offBtn.setEnabled(false);
          listBtn.setEnabled(false);
          findBtn.setEnabled(false);
          CStart.setEnabled(false);
          text.setText("Status: not supported");

          Toast.makeText(getApplicationContext(),"Your device does not support Bluetooth",
                 Toast.LENGTH_LONG).show();
      } else {
          text = (TextView) findViewById(R.id.text);
          onBtn = (Button)findViewById(R.id.turnOn);
          onBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                on(v);
            }
          });

          offBtn = (Button)findViewById(R.id.turnOff);
          offBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                off(v);
            }
          });

          //*********************************************************
          listBtn = (Button)findViewById(R.id.paired);
          listBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                list(v);
            }
          });

          //**********************************************************

         myListView.setOnItemSelectedListener(new OnItemSelectedListener (){

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, 
                    int pos, long id) {             
                // An item was selected. You can retrieve the selected item using
                 name1= new String (parent.getItemAtPosition(pos).toString());  
                 CStart = (Button) findViewById(R.id.Start) ;
                  CStart.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            open(v);
                            }
                        });
            }


           public void onNothingSelected(AdapterView<?> parent) {
                // Another interface callback
                Toast.makeText(getApplicationContext(),"Select a device" ,
                         Toast.LENGTH_LONG).show();
            }
          });

          //***********************************************************
          findBtn = (Button)findViewById(R.id.search);
          findBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                find(v);
            }
          });
         //***********************************************************
          myListView = (Spinner)findViewById(R.id.listView1);
          // create the arrayAdapter that contains the BTDevices, and set it to the ListView
          BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
          BTArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
          myListView.setAdapter(BTArrayAdapter);  

      }
   }
        //**********************************METHODE***********************


   protected void open(View v) {
    // TODO Auto-generated method stub
       Intent i = new Intent(this ,MainActivity2.class);
     //  i.putExtra("message",name1);
        startActivityForResult(i, 1);

}


public void on(View view){
      if (!myBluetoothAdapter.isEnabled()) {
         Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
         startActivityForResult(turnOnIntent, REQUEST_ENABLE_BT);

         Toast.makeText(getApplicationContext(),"Bluetooth turned on" ,
                 Toast.LENGTH_LONG).show();
      }
      else{
         Toast.makeText(getApplicationContext(),"Bluetooth is already on",
                 Toast.LENGTH_LONG).show();
      }
   }

   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       // TODO Auto-generated method stub
       if(requestCode == REQUEST_ENABLE_BT){
           if(myBluetoothAdapter.isEnabled()) {
               text.setText("Status: Enabled");
           } else {   
               text.setText("Status: Disabled");
           }
       }
   }

   public void list(View view){
      // get paired devices
      pairedDevices = myBluetoothAdapter.getBondedDevices();

      // put it's one to the adapter
      for(BluetoothDevice device : pairedDevices)
          BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());

      Toast.makeText(getApplicationContext(),"Show Paired Devices",
              Toast.LENGTH_SHORT).show();

   }

   final BroadcastReceiver bReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                 // Get the BluetoothDevice object from the Intent
                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 // add the name and the MAC address of the object to the arrayAdapter
                 BTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                 BTArrayAdapter.notifyDataSetChanged();
            }
        }
    };

   public void find(View view) {
       if (myBluetoothAdapter.isDiscovering()) {
           // the button is pressed when it discovers, so cancel the discovery
           myBluetoothAdapter.cancelDiscovery();
       }
       else {
            BTArrayAdapter.clear();
            myBluetoothAdapter.startDiscovery();

            registerReceiver(bReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));    
        }    
   }

   public void off(View view){
      myBluetoothAdapter.disable();
      text.setText("Status: Disconnected");

      Toast.makeText(getApplicationContext(),"Bluetooth turned off",
              Toast.LENGTH_LONG).show();
   }

   @Override
   protected void onDestroy() {
       // TODO Auto-generated method stub
       super.onDestroy();
       unregisterReceiver(bReceiver);
   }


}

【问题讨论】:

  • 显示 logcat 以查看崩溃的位置
  • 为什么startchat按钮点击监听在onItemSelected??
  • @NayraAhmed 所以我可以选择我想与之聊天的其他设备
  • @hrskrs 我添加了 logCat
  • @WaelGolli 看来你没有在AndroidManifest上注册接收者

标签: java android button spinner


【解决方案1】:

异常清楚地说明了以下内容:

Receiver not registered: com.example.javachat.MainActivity$1@418afa30

崩溃发生在这里:

03-24 19:48:32.967: E/AndroidRuntime(23058):at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:445)
03-24 19:48:32.967: E/AndroidRuntime(23058):  at com.example.javachat.MainActivity.onDestroy(MainActivity.java:229) 
03-24 19:48:32.967: E/AndroidRuntime(23058):at com.example.javachat.MainActivity.onCreate(MainActivity.java:136)

您在onDestroyunregisterReceiver,但您没有注册它的地方。你也想看看here,因为onItemSelected 将被调用Spinner 而无需用户操作。

但这还不是结束。 BroadcastReceiver 声明是错误的。由于您在本地使用广播接收器,将其绑定到Activity 生命周期,您应该使用LocalBroadcastManager,在onCreate/onDestroy 注册/取消注册(或其他生命周期回调,取决于您的需要)。因此,清单中的以下声明毫无意义:

 <receiver android:name=".bReceiver">
 </receiver>

因为您没有名为bReceiver 的类,所以您有一个局部变量(实际上应该成为类成员)bReceiver,它指向BroadcastReceiver 类的一个实例。

【讨论】:

  • 我在一些回放后将接收器添加到 android manifest ......如果你能让我更容易理解它会很棒,我还是这门语言的新手,我没有得到它如何解决我的问题。
  • @WaelGolli 你可以阅读这个vogella.com/tutorials/AndroidBroadcastReceiver/article.html 教程
  • 我想我明白了,我现在没有得到 contextwrapper /ondestroy/oncreat/ log cat 但应用程序仍然崩溃
  • 我设法让它在所有应用程序中运行,这是我的错,因为在我写“myListView = (Spinner)findViewById(R.id.listView1);”之前在 setOnItemSelectedListener 上使用了“mylistview” @nikis
【解决方案2】:

如果单击按钮导致崩溃,那么原因是 -

您已在 onItemSlected() 中将方法本地匿名内部类对象设置为侦听器。当方法执行完成时,该对象将被销毁。

因此,当 onItemSelected 完成时,您的侦听器对象已正确设置。但是在单击按钮时,会调用已保存的侦听器对象,该对象实际上已被垃圾收集器清除。

你不应该这样设置监听器。如果我确实正确理解了您的要求,您可以轻松地在您的项目单击侦听器之外设置侦听器。

【讨论】:

  • 我在不使用 Spinner 代码的情况下尝试了 Button Code 并且工作正常,然后我通过使用 Spinner 代码而不使用 Button 代码以其他方式进行操作,结果导致崩溃。
  • 您能否分享您遇到崩溃的最新代码以及日志中的堆栈跟踪?
猜你喜欢
  • 1970-01-01
  • 2011-05-26
  • 2013-08-20
  • 2021-08-28
  • 2012-05-09
  • 2010-11-08
  • 2014-01-24
  • 1970-01-01
  • 2015-12-21
相关资源
最近更新 更多