【问题标题】:Accessing methods from other class to Activity从其他类访问方法到 Activity
【发布时间】:2018-05-19 19:05:16
【问题描述】:

我需要将 AsynTask 的 OnPostExecute() 方法生成的 String 值设置为另一个 Activity 的 Textview,因为我使用了以下两种方法,但两种方法都失败了。

方法一:使用GetterSetter类

我对 android 还很陌生。我正在制作一个应用程序,我在其中遇到了这个特定问题。我正在从 BackgroundTask 类运行 asyncTask,而 BackgroundTask 正在从 StringGenerator 类运行。在此 AsyncTask 中,我将字符串的值设置为 getterSetter 类。

我的字符串生成器类 -->

public class StringGenerator {
        ...
        new BackgroundTask(context).execute(sb.toString());
        Intent intent = new Intent(context.getApplicationContext(),Answer.class);
        context.startActivity(intent);
        sb.setLength(0);

}

我的 BackgroundTask 类 -->

class BackgroundTask extends AsyncTask<String, Void, String> {

    Context context;

    GetterSetter getterSetter;

    ...   

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.d("Answer",s);
        getterSetter = new GetterSetter();
        getterSetter.setString(s);
    }
}

我的 GetterSetter 类,这里的日志打印出正确的字符串。所以,这里设置了字符串,我已经验证过了。 -->

class GetterSetter{

    private String string;

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
        Log.d("S1",string);
        Log.d("S2",this.string);
    }
}

从这个 getterSetter 类中,我想访问字符串并将其设置到 textview 到另一个名为 Answer Activity 的活动上。

我的回答活动 -->

public class Answer extends AppCompatActivity {

    GetterSetter getterSetter;

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

        getterSetter = new GetterSetter();
        ((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
    }
}

这个方法的问题是 -->

但是textview上设置的String值是空的,所以打印 没有什么。另外,我尝试记录字符串。

方法2:使用SharedPreferences,但它总是给我默认值“”(空)。

我的 StringGenerator 类 -->

public class StringGenerator {
            ...
            new BackgroundTask(context).execute(sb.toString());
            Intent intent = new Intent(context.getApplicationContext(),Answer.class);
            context.startActivity(intent);
            sb.setLength(0);

    }

我的 BackgroundTask 类 -->

class BackgroundTask extends AsyncTask<String, Void, String> {

    Context context;
    SharedPreferences.Editor editor;

    BackgroundTask(Context context) {
        this.context = context;
        editor = context.getSharedPreferences("SolutionString",context.MODE_PRIVATE).edit();
    }

    ...

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.d("Answer", s);
        editor.putString("Solution",s);
        editor.apply();
    }
}

我的答题课-->

public class Answer extends AppCompatActivity {

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

        SharedPreferences sharedPreferences = getSharedPreferences("SolutionString", MODE_PRIVATE);
        ((TextView)findViewById(R.id.SetSteps)).setText(sharedPreferences.getString("Solution",""));
    }
}

这个方法的问题是 -->

这个方法只会在第一次设置正确的输出字符串,在第二次之后这个方法将打印默认值“”(空)。我尝试通过调试这个方法打印日志和日志中的字符串值不为空,我在日志中得到了正确的值。 所以,我认为这种方法的问题在于 sharedpreferences 值的更新。我也在 stackoverflow 上对此进行了研究,并尝试了以下解决方案,但没有任何效果。

  1. SharedPreferences return only default value
  2. getPreferences always returns default value

还有更多。

谁能告诉我如何在第一种方法中访问 OnCreate Activity 中的字符串?或者对于第二种方法,我需要获取 SharedPreferences 的更新值。

我不想创建另一个意图,因为我已经从字符串生成器类运行意图。

【问题讨论】:

  • 你的后台任务在 Answer 类里面吗?
  • 不,这是不同的类别。
  • 你在哪里初始化异步类?另外你为什么在与主类不同的类中创建一个异步任务?
  • 我只是调用了构造函数并执行了doinbackground方法,我不需要使用对象进行初始化,并且由于性能问题我需要同时运行两个进程,如果我不使用AsyncTask需要很长时间。我现在将尝试使用 sharedpreferences 来存储和获取值,我认为这个 getter 和 setter 不会起作用。
  • 你在哪里见过这样使用它?

标签: java android sharedpreferences


【解决方案1】:

首先new GetterSetter() 将创建一个新对象...现在让我们看看内存是如何工作的...

class BackgroundTask extends AsyncTask<String, Void, String> {

    Context context;

    GetterSetter getterSetter;

    ...   

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.d("Answer",s);
        getterSetter = new GetterSetter(); // assume is stored at address  2000 in the memory
        getterSetter.setString(s);
    }
}

public class Answer extends AppCompatActivity {

    GetterSetter getterSetter;

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

        getterSetter = new GetterSetter();// assume stored at 2008 in the memory , hence the string private String string does not have any value...
        ((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
    }
}

现在是要点:-

  1. private String string; 如果您将其声明为private String string = "";,则不会发生空指针异常。

  2. 你应该只有一次 GetterSetter getterSetter; 初始化 getterSetter = new GetterSetter(); 然后该值将持续存在......如果你在单独的文件中同时拥有 BackgroundTaskAnswer Answer 类将无法见BackgroundTaskGetterSetter...

  3. 宁可在Activity类中包含BackgroundTask,在onPostExecute中调用textview.setText...

公共类答案扩展 AppCompatActivity {

GetterSetter getterSetter;

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

    getterSetter = new GetterSetter();

}

class BackgroundTask extends AsyncTask<String, Void, String> {

Context context;

...   

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.d("Answer",s);
    getterSetter.setString(s);

    ((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());
}

} }

  1. 如果您坚持使用不同的文件,则应先调用 BackgroundTask,然后

类 BackgroundTask 扩展 AsyncTask {

Context context;

public static GetterSetter getterSetter; // this will store the object in memory and the value will persist between classes...

...   

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.d("Answer",s);
    getterSetter = new GetterSetter();
    getterSetter.setString(s);
    // the activity Answer should start anywhere after this to get the correct value...
}

}

public class Answer extends AppCompatActivity {

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

        ((TextView)findViewById(R.id.SetSteps)).setText(BackgroundTask.getterSetter.getString());
    }
}

希望对你有帮助...

【讨论】:

  • 我已经应用了第二种方法,但它不起作用,仍然打印空字符串。 Nullpointer 异常已解决。
  • 在执行 AsyncTask 后,我正在从 StringGenerator 类传递意图。所以,我想运行主线程进行 UI 更新和 AsyncTask 设置字符串值。
  • 我已经更新了答案,请查看。抱歉,我尝试了您的解决方案,但没有奏效。
  • Startactivity 应该在 onPostExecute... protected void onPostExecute(String s) { super.onPostExecute(s); Log.d("答案",s); getterSetter = new GetterSetter(); getterSetter.setString(s); Intent intent = new Intent(context.getApplicationContext(),Answer.class); context.startActivity(intent); }
  • 但它不会工作,因为你有 2 个新的(分配在不同的内存)GetterSetter 声明......你可以在 GetterSetter 的 StringGenerator 中创建一个公共静态变量,然后通过我的答案(2 和 4 ) 再次...
【解决方案2】:

当您创建一个新对象时,现有对象中的数据将被销毁。因此,完成上述任务的最简单方法是发送带有意图的对象。您可以在 PostExecute 或单击第一个 Activity 中的按钮时执行此操作。

    Intent intent = new Intent(MainActivity.this, Answer.class);
    intent.putExtra("Object", getterSetter);
    startActivity(intent);

并且您的对象,即 GetterSetter 必须将 Serializable 实现为:

    class GetterSetter implements Serializable

在您的另一个活动中,即 Answer.java 您必须接收以下意图:

    Intent rcv = getIntent();
    GetterSetter getterSetter = (GetterSetter) rcv.getSerializableExtra("Object");,

((TextView)findViewById(R.id.SetSteps)).setText(getterSetter.getString());

【讨论】:

  • 我可以通过 2 个意图吗? 1 来自 StringGenerator 和 1 来自 OnPostexecute 方法?我有性能问题,所以我需要同时运行这两种方法。
  • 您不需要传递 2 个意图。您只能在此意图中传递对象。公共类 StringGenerator { ... new BackgroundTask(context).execute(sb.toString()); Intent intent = new Intent(context.getApplicationContext(),Answer.class); intent.putExtra("对象", getterSetter); context.startActivity(intent); sb.setLength(0);
  • 为什么需要实现可序列化?
  • 通过使用 Serializable 可以将对象的状态转换为字节流。并按意图发送。
猜你喜欢
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 2012-03-15
相关资源
最近更新 更多