java.lang.IollegalStateException:创建自定义适配器时,在onCreate()之前,Act



我收到一个错误,上面写着:

java.lang.IollegalStateException:在onCreate((之前,系统服务不可用于Activities

尽管我所做的每一个操作都在onCreate()之后。

我有一个自定义适配器,有4个按钮。当单击其中一个按钮时,它最终调用updateList()函数,该函数应该用新的详细信息更新列表。

这是代码:主要活动.java

public class MainActivity extends Activity {
static int accountsCount = 0;
static FileWorker fileWorker;
static File directory;
ListView ledgerListView;
TextView noAccountsTextView;
TextView accountHierarchy;
EditText accountName;
EditText accountLimit;
AlertDialog.Builder accountDialogBuilderChild;
AlertDialog accountDialogChild;
static ArrayList<AccountsView> ledgerList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean introDone = preferences.getBoolean("intro_done", false);
boolean howToDone = preferences.getBoolean("howto_done", false);
boolean prefFilesCreated = preferences.getBoolean("files_created", false);
if(!introDone || !howToDone) {
Intent introActivity = new Intent(this, IntroActivity.class);
startActivity(introActivity);
}
noAccountsTextView = findViewById(R.id.noAccountsTextView);
ledgerListView = findViewById(R.id.mainListView);
fileWorker = new FileWorker();
directory = getFilesDir();
if(!prefFilesCreated) {
boolean filesCreated = fileWorker.createFiles(directory);
if(filesCreated) {
SharedPreferences.Editor prefEditor = preferences.edit();
prefEditor.putBoolean("files_created", true);
prefEditor.apply();
}
}
accountsCount = fileWorker.countAccounts(directory);
setMainActivityView();
}
public void addChildAccountDialog(Context context, int pos) {
String hierarchy = ledgerList.get(pos).getAccountName();
String renewalType = ledgerList.get(pos).getRenewalType();
accountDialogBuilderChild = new AlertDialog.Builder(context);
accountDialogBuilderChild.setTitle(R.string.add_child_account_dialog_title);
accountDialogBuilderChild.setPositiveButton("Ok",
(dialogInterface, i) -> addChildAccount(hierarchy, renewalType));
accountDialogBuilderChild.setNegativeButton("Cancel",
(dialogInterface, i) -> dialogInterface.cancel());
accountDialogBuilderChild.setView(R.layout.dialog_add_child_account);
accountDialogChild = accountDialogBuilderChild.create();
accountDialogChild.show();
accountHierarchy = accountDialogChild.findViewById(R.id.accountHierarchyValueTV);
accountHierarchy.setText(hierarchy);
accountName = accountDialogChild.findViewById(R.id.accountNameDialogET);
accountLimit = accountDialogChild.findViewById(R.id.accountLimitDialogET);
}
private void addChildAccount(String hierarchy, String renewalType) {
String accName = hierarchy.concat(formatAccountName(accountName
.getText().toString()));
double accLimit = Double.parseDouble(accountLimit.getText().toString());
fileWorker.addChildAccount(directory,
accName,
renewalType,
accLimit);
setMainActivityView();
}
private void setMainActivityView() {
accountsCount = fileWorker.countAccounts(directory);
if(accountsCount <= 0) {
ledgerListView.setVisibility(View.GONE);
noAccountsTextView.setVisibility(View.VISIBLE);
} else {
updateList();
ledgerListView.setVisibility(View.VISIBLE);
noAccountsTextView.setVisibility(View.GONE);
}
}
public void updateList() {
fileWorker.sortAccounts(directory);
ledgerList = fileWorker.getAccountsList(directory);
AccountsViewAdapter ledgerAdapter = new
AccountsViewAdapter(this, ledgerList);
ledgerListView.setAdapter(ledgerAdapter);
}
public String formatAccountName(String accName) {
accName = accName.trim().toLowerCase();
accName = accName.replace(' ', '_');
accName = accName.replace('/', '_');
if(accName.charAt(0) != '/') {
accName = "/".concat(accName);
}
return accName;
}
public void onBackPressed() {
new AlertDialog.Builder(this)
.setTitle("Exit")
.setMessage("Are you sure?")
.setPositiveButton("Yes", (dialog, which) -> this.finishAffinity())
.setNegativeButton("No", null)
.show();
}
}

这是cutomAdapter代码:

public class AccountsViewAdapter extends ArrayAdapter<AccountsView> {
TextView accountName;
TextView renewalType;
TextView limitValue;
TextView balanceValue;
Button buttonAddAccount;
Button buttonEditAccount;
Button buttonIncreaseBalance;
Button buttonDecreaseBalance;
MainActivity mainActivity;
public AccountsViewAdapter(Context context, ArrayList<AccountsView> arrayList) {
super(context, 0, arrayList);
}
public View getView(int position, View convertView, ViewGroup parent) {
View currentItemView  = convertView;
if(currentItemView == null) {
currentItemView = LayoutInflater.from(getContext())
.inflate(R.layout.listview_row, parent, false);
}
AccountsView currentAccount = getItem(position);
assert currentAccount != null;
accountName = currentItemView.findViewById(R.id.accountNameValueTextView);
renewalType = currentItemView.findViewById(R.id.textViewRenewalTypeValue);
limitValue = currentItemView.findViewById(R.id.limitValueTextView);
balanceValue = currentItemView.findViewById(R.id.balanceValueTextView);
buttonAddAccount = currentItemView.findViewById(R.id.addAccountButton);
buttonEditAccount = currentItemView.findViewById(R.id.editAccountButton);
buttonIncreaseBalance = currentItemView.findViewById(R.id.increaseBalanceButton);
buttonDecreaseBalance = currentItemView.findViewById(R.id.decreaseBalanceButton);
accountName.setText(currentAccount.getAccountName());
renewalType.setText(currentAccount.getRenewalType());
limitValue.setText(currentAccount.getAmountLimit());
balanceValue.setText(currentAccount.getBalanceValue());
mainActivity = new MainActivity();
buttonAddAccount.setOnClickListener(v -> {
mainActivity.addChildAccountDialog(buttonAddAccount.getContext(), position);
});
return currentItemView;
}
}

据我所知,当我点击";buttonAddAccount;按钮我试着用MainActivity.this替换MainActivity中的上下文,但无济于事。

这是错误日志:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.biotstoiq.seshat, PID: 18232
java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:6715)
at android.view.LayoutInflater.from(LayoutInflater.java:299)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:216)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:210)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:196)
at org.biotstoiq.seshat.AccountsViewAdapter.<init>(AccountsViewAdapter.java:28)
at org.biotstoiq.seshat.MainActivity.updateList(MainActivity.java:179)
at org.biotstoiq.seshat.MainActivity.setMainActivityView(MainActivity.java:170)
at org.biotstoiq.seshat.MainActivity.addChildAccount(MainActivity.java:161)
at org.biotstoiq.seshat.MainActivity.lambda$addChildAccountDialog$2$org-biotstoiq-seshat-MainActivity(MainActivity.java:140)
at org.biotstoiq.seshat.MainActivity$$ExternalSyntheticLambda2.onClick(Unknown Source:6)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:201)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:230)
at android.app.ActivityThread.main(ActivityThread.java:7875)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:526)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
I/Process: Sending signal. PID: 18232 SIG: 9

fileWorker代码不在这里,因为我认为这里不需要它。

  1. 永远不要用new ActivityClass实例化"活动"。这并不能正确地初始化它。只有安卓框架才能正确地初始化活动,而你可以通过Intent来完成。

  2. 即使您可以初始化这样的"活动",它也是错误的。你不想在一个新实例上调用该函数,你想在你运行的实例上调用它

  3. 您不应该有任何需要特定"活动"的视图或适配器类。您应该使用将处理程序传递到适配器中的接口。这种方法更容易测试,也更容易正确。即使您的代码有效,也几乎不可能进行单元测试。

最新更新