尝试将按钮用作导航菜单时未处理的异常类型

时间:2012-07-31 15:53:05

标签: java android button

我正在尝试将不同的按钮链接到不同的活动。所以实际上创建了一个导航菜单。

我正在尝试使用更少的代码,因此我尝试创建一个函数,我可以传递值,以便动态识别按钮id并为其提供活动的链接。

这是我的xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/nav1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="@string/nav1" />

    <Button
        android:id="@+id/nav2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/nav1"
        android:text="@string/nav2" />

</RelativeLayout>

这是我的Java:

package com.example.myfirstapp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Nav extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_nav);

        String nav1 = "nav1";
        String nav2 = "nav2";

        String MainActivity = "MainActivity";
        String SQLite = "SQLite";

        navButton(nav1, MainActivity);
        navButton(nav2, SQLite);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_nav, menu);
        return true;
    }

    private void navButton(String buttonId, String activityName){
        String bId = buttonId;
        final Class<?> aName = Class.forName(activityName);
        int resId = getResources().getIdentifier(bId, "id", getPackageName());
        Button b = (Button) findViewById(resId);
        OnClickListener onClickListener = new OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Nav.this, aName);
                startActivity(i);
            }};
        b.setOnClickListener(onClickListener);
    }
}

我在网上收到错误:

final Class<?> aName = Class.forName(activityName);

它说:

Unhandled exception type ClassNotFoundException

或者说这是最简单的方法

3 个答案:

答案 0 :(得分:3)

每当我使用Class.forName时,我都会传递一个限定名称,例如“mypackage.myclass”。我不确定它是否适用于不合格的名称。

在任何情况下,为什么传入字符串然后执行forName?为什么不更改签名以获取Class对象并只传入MainActivity.class等?然后,您将在编译时捕获任何缺少的类或拼写错误,而不是运行时。

更新以回应评论

public class Nav extends Activity { 

  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_nav); 

    navButton("nav1", MainActivity.class); 
    navButton("nav2", SQLite.class); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_nav, menu); 
    return true; 
} 

private void navButton(String buttonId, Class aName){ 
    String bId = buttonId; 
    // aName now passed in so doesn't need to be looked up
    ... etc ...
} 
} 

我认为上面应该编译并运行。我没有尝试过,但我做过类似的事情。根据您的软件包的设置方式,您可能需要导入MainActivity和SQLite,或者完全质量它们,以获取.class。

答案 1 :(得分:0)

您是否在应用程序的AndroidManifest.xml

中定义了您的活动

答案 2 :(得分:0)

您没有捕获已检查的异常ClassNotFoundException。您需要将相关代码包装在try / catch块中,例如

try {
    final Class<?> aName = Class.forName(activityName);
    //etc...
} catch (ClassNotFoundException e) {
    //Do whatever cleanup you have to do in case this situation occurs.
}

但这似乎是一种设置点击监听器的异常尴尬方式。为什么你不能只将类本身传递给你的navButton方法而不是做反射(如果有替代方法,这应该总是最后的手段)?