问题
Hey I've just upgraded my app to AppCompat v22.1.0 and got this exception
Caused by: java.lang.IllegalArgumentException: AppCompat does not support the current theme features
at android.support.v7.app.AppCompatDelegateImplV7.ensureSubDecor(AppCompatDelegateImplV7.java:360)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:246)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
I found soln. here https://stackoverflow.com/a/29790071/2781359
Still the problem wasn't solved because I was calling the setContentView after super.onCreate, in the ConnectionWifiEditActivity
Class.
When I changed this it throws NullPointerException
How Can I Solve this?
Caused by: java.lang.NullPointerException
at Client.Activity.connection.ConnectionEditActivity.onResume(ConnectionEditActivity.java:46)
at Client.Activity.connection.ConnectionWifiEditActivity.onResume(ConnectionWifiEditActivity.java:81)
ConnectionWifiEditActivity
public class ConnectionWifiEditActivity extends ConnectionEditActivity implements OnClickListener
{
private ConnectionWifi connection;
private EditText host;
private EditText port;
Button scan;
ListView lv;
private Toolbar mToolbar;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.connectionwifiedit);
lv = (ListView) findViewById(android.R.id.list);
this.connection = (ConnectionWifi) connectionParam;
mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
this.host = (EditText) this.findViewById(R.id.host);
this.port = (EditText) this.findViewById(R.id.port);
SnackbarManager.show(
Snackbar.with(getApplicationContext()) // context
.type(SnackbarType.MULTI_LINE) // Set is as a multi-line snackbar
.text(R.string.tip) // text to be displayed
.duration(Snackbar.SnackbarDuration.LENGTH_INDEFINITE)
, this);
}
public void Save(View v){
this.finish();
}
@Override
public void onClick(View v)
{
}
protected void onResume()
{
super.onResume();
this.host.setText(this.connection.getHost());
this.port.setText(Integer.toString(this.connection.getPort()));
}
protected void onPause()
{
super.onPause();
this.connection.setHost(this.host.getText().toString());
this.connection.setPort(Integer.parseInt(this.port.getText().toString()));
}}
ConnectionEditActivity
public static Connection connectionParam;
private Connection connection;
private EditText name;
private EditText password;
public class ConnectionEditActivity extends AppCompatActivity implements OnClickListener
{
public static Connection connectionParam;
private Connection connection;
private Button save;
private EditText name;
private EditText password;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected void onResume()
{
super.onResume();
this.name.setText(this.connection.getName());
this.password.setText(this.connection.getPassword());
}
protected void onPause()
{
super.onPause();
this.connection.setName(this.name.getText().toString());
this.connection.setPassword(this.password.getText().toString());
}
public void onClick(View v)
{
if (v == this.save)
{
this.finish();
}
}
}
Connection
public abstract class Connection implements Comparable<Connection>, Serializable
{
private static final long serialVersionUID = 1L;
public static final int TYPE_COUNT = 2;
public static final int WIFI = 0;
public static final int BLUETOOTH = 1;
private String name;
private String password;
public Connection()
{
this.name = "";
this.password = RemoteItConnection.DEFAULT_PASSWORD;
}
public static Connection load(SharedPreferences preferences, ConnectionList list, int position)
{
Connection connection = null;
int type = preferences.getInt("connection_" + position + "_type", -1);
switch (type)
{
case WIFI:
connection = ConnectionWifi.load(preferences, position);
break;
case BLUETOOTH:
connection = ConnectionBluetooth.load(preferences, position);
break;
}
connection.name = preferences.getString("connection_" + position + "_name", null);
connection.password = preferences.getString("connection_" + position + "_password", null);
return connection;
}
public void save(Editor editor, int position)
{
editor.putString("connection_" + position + "_name", this.name);
editor.putString("connection_" + position + "_password", this.password);
}
public abstract RemoteItConnection connect(RemoteIt application) throws IOException;
public abstract void edit(Context context);
protected void edit(Context context, Intent intent)
{
ConnectionEditActivity.connectionParam = this;
context.startActivity(intent);
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public int compareTo(Connection c)
{
return this.name.compareTo(c.name);
}
}
回答1:
Since you want to get some ui elements in the super method, you have to find a way to define the layout in the superclass. It is the reason because you are getting an NPE as described in the other answers.
You can use the setContentView()
in the superclass, using a method to return the layout to use.
In this way you can override the layout in the sub class, overriding the method.
For example you can use something like setContentView(getLayoutId()):
public class ConnectionEditActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(getLayoutId()); //pay attention here...
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
}
protected int getLayoutId(){
//....
}
}
And you can override it in other activity, where you can avoid the setContentView
method.
public class ConnectionWifiEditActivity extends ConnectionEditActivity{
@Override
protected int getLayoutId(){
return R.layout.connectionwifiedit;
}
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(); //comment this line
//..
}
}
回答2:
Just add this to your style (both are needed)
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
and in ConnectionEditActivity you call findViewById BEFORE calling setContentView it will always return null. So your view will be always null.
this.connection = connectionParam;
this.name = (EditText) this.findViewById(R.id.name);
this.password = (EditText) this.findViewById(R.id.password);
来源:https://stackoverflow.com/questions/29937319/how-to-setcontentview-before-super-oncreate-while-using-appcompat-v22-1-0