简体   繁体   English

如何从Runnable线程获取局部变量

[英]How to get a local variable from a Runnable Thread

I have a helper (Not an activity) class that makes a query to an API which has a public function called run() and runs on a new thread (As per Android specifications). 我有一个帮助器(非活动)类,它对API进行查询,该API具有一个名为run()的公共函数,并在一个新线程上run()根据Android规范)。 My MainActivity creates a new MakeQuery object and runs its run() function: 我的MainActivity创建一个新的MakeQuery对象并运行其run()函数:

MakeQuery q = new MakeQuery();
q.run();

However, I need to access a variable from within the thread. 但是,我需要从线程中访问变量。 Below is a short code sample: 以下是一个简短的代码示例:

public class MakeQuery implements Runnable {

    private void setNewString(String localThreadString){
       //NewString comes out null...
       NewString  = localThreadString;
    }

    public void run() {
        new Thread(new Runnable() {
            public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

                API Api = new API(keys and tokens);

                //queryAPI() returns string
                setNewString(queryAPI(Api, term1, term2));

                //Don't know how to send intent from here (No context), 
                //I would like:
                Intent i = new Intent(MainActivity.class, AnotherActivity.class)
        }
    }).start();
}

ASYNCTASK 的AsyncTask

//This runs in background thread
@Override
protected Void doInBackground(Void... params) {
    API Api = new API(keys and tokens);

    setNewString(queryAPI(Api, string1, string2));

    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    Intent intent = new Intent(mContext, Activity2.class);
    intent.putExtra("NewString", NewString);
    Log.d(MYTAG, NewString);
}

MainActivity 主要活动

public void buttonPressed(View view) {
    Intent intent = new Intent(this, Activity2.class);
    ...
    MakeQuery task = new MakeQuery(this);
    task.execute();

    startActivity(intent);
}

I have tried to look online for hours. 我试着在网上看几个小时。 I have tried to do AsyncTask , but I am not sure how to implement that with what I have. 我曾尝试过做AsyncTask ,但我不知道如何用我拥有的东西来实现它。 Furthermore, using localThread<String> did not help. 此外,使用localThread<String>没有帮助。

TLDR: I would like to know if it's possible to get NewString so I can pass it through an Intent to another Activity. TLDR:我想知道是否可以获取NewString,以便我可以通过Intent将其传递给另一个Activity。

The Solution Do not use Runnable , create a new AsyncTask as shown below. 解决方案不要使用Runnable ,创建一个新的AsyncTask ,如下所示。 Also, make sure that the StartActivity is in the helper class and not in the MainActivity . 此外,请确保StartActivity位于帮助程序类中,而不是MainActivity This was because I was not waiting for the task to finish before starting the new activity. 这是因为我没有在开始新活动之前等待完成任务。

Here is an implementation using async task: 以下是使用异步任务的实现:

public class MakeQueryTask extends AsyncTask<Void, Void, Void> {

    private Context mContext;

    private String newString;

    public MakeQueryTask(Context context) {
        mContext = context;
    }

    //This runs on a background thread
    @Override
    protected Void doInBackground(Void... params) {


        API Api = new API(keys and tokens);

        //queryAPI() returns string
        setNewString(queryAPI(Api, term1, term2));

        //You should start your activity on main thread. Do it in onPostExecute() which will be invoked after the background thread is done
        //Intent i = new Intent(mContext, AnotherActivity.class);
        //mContext.startActivity(intent);
        return null;
    }

    private void setNewString(String localThreadString){
        newString  = localThreadString;
    }

    //This will run on UI thread
    @Override
    protected void onPostExecute(Void aVoid) {
        Intent intent = new Intent(mContext, AnotherActivity.class);
       mContext.startActivity(intent);
    }
}

And you would execute like this: 你会这样执行:

 MakeQueryTask task = new MakeQueryTask(this); //Here this is an activity (context)
 task.execute();

If you are calling this runnable from an activity or service , you could pass in a context in the constructor. 如果从activityservice调用此runnable ,则可以在构造函数中传入context And just start the activity with the intent in the run() function. 然后在run()函数中启动intent

public class MakeQuery implements Runnable {

    private Context context;

    public MakeQuery(Context context) {
        this.context = context;
    }

    private void setNewString(String localThreadString){
       //NewString comes out null...
       NewString  = localThreadString;
    }

    public void run() {
        new Thread(new Runnable() {
            public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

                API Api = new API(keys and tokens);

                //queryAPI() returns string
                setNewString(queryAPI(Api, term1, term2));

                Intent intent = new Intent(MainActivity.class, AnotherActivity.class)
                context.startActivity(intent);
        }
    }).start();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM