1

我对编程很陌生。

我正在尝试制作一个包含两个活动的简单应用程序,其中第二个活动可以更改第一个活动的文本。我知道它可以使用意图来完成,但我想知道是否有更直接的方法,例如使用第二个活动从第一个活动调用函数?

这是我到目前为止的代码:

MainActivity,其中包含一个 TextView 和一个用于打开第二个活动的按钮:

public class MainActivity extends Activity {

TextView textview;
Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textview = (TextView) findViewById(R.id.et2);
    button = (Button) findViewById(R.id.b1);

    button.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent(MainActivity.this, ChangeText.class);
            startActivity(intent);
        }
    });
}

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

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

public void changetext(String message) {
    textview.setText(message);
}
}

第二个活动 ChangeText 包含一个 EditText 和一个按钮,该按钮应该更改 MainActivity 中 TextView 的文本,然后自行完成:

public class ChangeText extends Activity{

EditText edittext;
Button button;
private MainActivity mainclass;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.change_text);

    edittext = (EditText)findViewById(R.id.et2);
    button = (Button)findViewById(R.id.b2);

    button.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
        String message = edittext.getText().toString(); 
        mainclass.changetext(message);
        finish();
        }
    });
}
}

如您所见,我试图通过在 MainActivity 中创建一个公共函数来使应用程序工作,该函数接收一个字符串并使用它设置 TextView,然后我从 ChangeText 活动中调用此函数。

问题:它一直在崩溃!谁能告诉我如何才能完成这项工作?

4

5 回答 5

1

好像我在一周左右前回答了几乎完全相同的问题,所以这可能是重复的,但我似乎找不到原始问题。

简短的回答是否定的——你不能从另一个 Activity 调用 Activity 中的方法。问题是对于正常的编程目的,一次只存在一个活动*。

如果您采取措施来规避这一点,那么您就有可能导致一些重大问题,包括高内存使用、空指针异常等。

做到这一点的正确方法确实是通过 Intent 系统。

*当活动变为非活动状态时,它们实际上可能会或可能不会被销毁,这取决于您如何使用后堆栈。但是,您应该始终对它们是否在它们变得不活动时被销毁进行编程 - 阅读、理解并尊重 Activity 生命周期。

于 2015-03-21T17:03:54.697 回答
0

对于像您的应用程序这样简单的事情,“最直接”的方法是使用意图和 startActivityForResult,它们在您的主要活动中实现 onActivityResult。

即使您正确地传递了 Activity 引用,您也会遇到的问题是它们不能保证同时运行。

除了 Intents 之外的其他方法是使用与 Activity 无关的类。扩展应用程序的类中的后台服务或静态变量。我很少再使用应用程序类来支持服务和绑定活动它们。

如果我在项目中使用 EventBus,他们可以发送 Sticky 事件,这些事件将保存数据直到被清除。

于 2015-03-21T17:20:49.663 回答
0

Android 使用消息传递机制在其组件之间进行通信。这种消息传递机制对 Android 来说是必不可少的,因此您应该使用它。正如您已经说过的,消息传递是由 Intents 实现的。;-)

如果您想要更复杂的东西,请使用 EventBus 或实现您自己的订阅/发布机制来满足您的需求。

于 2015-03-21T17:51:01.053 回答
0

使用静态变量

例子

在您的 MainActivity 定义

public static String msg = null;

然后在您的 ChangeText 活动中将更改的文本分配给它

MainActivity.msg = edittext.getText().toString();

现在在您的主要活动中覆盖 onResume() 方法

if(msg != null){ textview.setText(msg); msg = null; }

于 2015-03-21T18:30:33.933 回答
0

您必须使用 LocalBroadCast Manager 才能这样做

这是具有必须由另一个活动更新的 TextView 的 MainActivity

 import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
 import android.support.v4.content.LocalBroadcastManager;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.TextView;




public class MainActivity extends Activity {

  TextView txt;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txt=(TextView)findViewById(R.id.txt1);
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
            new IntentFilter("custom-event-name"));

}


private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String s1= intent.getStringExtra("myString");
        getIt(s1);
    }
};


@Override
protected void onDestroy() {
    // Unregister since the activity is about to be closed.
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    super.onDestroy();
}


public void getIt(String s)
{

       System.out.println(s);
      txt.setText(s);

}

public void go(View view)

{

  Intent intent = new Intent(this,WriteText.class);
startActivity(intent);


}


}

这是包含 EditText 的 Activity,它更新了上一个活动中的 TextView

 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.content.LocalBroadcastManager;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.EditText;




 public class WriteText extends Activity {

  EditText ed1;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_write_text);
    ed1 = (EditText)findViewById(R.id.textView);
}




 public void come(View view){


Intent intent = new Intent("custom-event-name");
intent.putExtra("myString", ed1.getText().toString());
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

 }



}

这对我有用,希望它也对你有用

于 2015-03-21T21:00:00.100 回答