Android 异步任务,doInBackground不';好像不行

Android 异步任务,doInBackground不';好像不行,android,android-asynctask,Android,Android Asynctask,我有那个任务代码 public class DiceTask extends AsyncTask<Socket, Void, int[]> { private int[] arrayFromServer = new int[8]; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected int[] doInBackground(Socket...param

我有那个任务代码

public class DiceTask extends AsyncTask<Socket, Void, int[]> {

private int[] arrayFromServer = new int[8];

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected int[] doInBackground(Socket...params) {
    Socket soc = params[0];

    try {
        ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
        int[] tempArray = (int[]) (ois.readObject());
        return tempArray;
    } catch (IOException | ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return null;
    }

}

@Override
protected void onProgressUpdate(Void...arg1) {

}

@Override
protected void onPostExecute(int[] result) {
    arrayFromServer = result;

}

public int[] getTempDice() {
    return arrayFromServer;
}
}
在这里,我得到一个
null tempArray
。如果我将我的
onPreExecute
更改为此

@Override
protected void onPreExecute() {
    super.onPreExecute();
    for(int i = 0; i < arrayFromServer.length; i++) {
        arrayFromServer[i] = 1;
    }
}

我可以在服务器中看到结果。

异步任务的子线程与主线程并行运行,您正在尝试在启动
线程后立即从服务器访问属性
arrayFromServer
。建议您使用回调来重试所需的值,确保在
线程
完成后获得该值

进行以下更改可以解决您的问题。如果你明白,请告诉我

public class DiceTask extends AsyncTask<Socket, Void, int[]> {

    public interface Callback {
        void onDone(int[] arrayFromServer);
    }

    private Callback mCallback;

    public DiceTask(Callback c) {
        mCallback = c;
    }

    @Override
    protected int[] doInBackground(Socket...params) {
        Socket soc = params[0];

        try {
            ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
            int[] tempArray = (int[]) (ois.readObject());
            return tempArray;
        } catch (IOException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }

    }


    @Override
    protected void onPostExecute(int[] result) {
        mCallback.onDone(result);
    }

}




rollDiceButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        rollDiceButton.setEnabled(false);
        rollDice();
        new DiceTask(new Callback() {
             public void onDone(int[] tempArray) {
                  printDice(tempArray,pDice);
                  clickableDice(pDice);
             }
        }).execute(socket);

    }
});
公共类任务扩展了异步任务{
公共接口回调{
void onDone(int[]数组来自服务器);
}
专用回调mCallback;
公共任务(回调c){
mCallback=c;
}
@凌驾
受保护的int[]doInBackground(套接字…参数){
插座soc=参数[0];
试一试{
ObjectInputStream ois=新的ObjectInputStream(soc.getInputStream());
int[]tempArray=(int[])(ois.readObject());
返回数组;
}捕获(IOException | ClassNotFoundException e){
//TODO自动生成的捕捉块
e、 printStackTrace();
返回null;
}
}
@凌驾
受保护的void onPostExecute(int[]结果){
mCallback.onDone(结果);
}
}
rollDiceButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
rollDiceButton.setEnabled(错误);
滚动骰子();
新任务(新回调(){
公共空onDone(int[]临时数组){
printDice(tempArray、pDice);
可点击骰子(pDice);
}
}).执行(套接字);
}
});

您不需要在AsyncTask类定义中实现
onPostExecute
。您也不需要
getTempDice
函数。您只需要在匿名类中重写
onPostExecute
,并在其中运行UI代码

rollDiceButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        rollDiceButton.setEnabled(false);
        rollDice();
        task = new DiceTask() {
            @Override
            public void onPostExecute(int[] result) {
                tempArray = result;
                printDice(tempArray,pDice);
                clickableDice(pDice);
            }
        }.execute(socket);
    }
});

这里不鼓励只使用代码的答案,所以。虽然他们可能会解决问题,但更重要的是说明问题是什么。感谢您让我知道这是真的,但如果它是
活动的内部类
,那么任务完成后要运行的代码也可以放在
onPostExecute()
中,那么实际上不需要回调。没错,现在,您需要为自己选择更好的方法。@betorcs很好,首先感谢您的回答。事实上,我无法理解您在这里做什么
静态类回调{void onDone(int[]arrayFromServer);}
,因为即使是编译器也说这是错误的。我想缺少了一些内容。我不认为您的结果在调用execute之后就可用。您可能希望向异步任务添加回调/侦听器。此外,异步任务是不可重用的。您只能在每个AsyncTask实例上调用一次“.execute”方法。@tato.rodrigo是的,我知道每次调用都需要更多实例,但我正在努力使该方法起作用,我会找到解决办法。谢谢你的回复。它很有效,100%可以理解。非常感谢。
public class DiceTask extends AsyncTask<Socket, Void, int[]> {

    public interface Callback {
        void onDone(int[] arrayFromServer);
    }

    private Callback mCallback;

    public DiceTask(Callback c) {
        mCallback = c;
    }

    @Override
    protected int[] doInBackground(Socket...params) {
        Socket soc = params[0];

        try {
            ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
            int[] tempArray = (int[]) (ois.readObject());
            return tempArray;
        } catch (IOException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }

    }


    @Override
    protected void onPostExecute(int[] result) {
        mCallback.onDone(result);
    }

}




rollDiceButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        rollDiceButton.setEnabled(false);
        rollDice();
        new DiceTask(new Callback() {
             public void onDone(int[] tempArray) {
                  printDice(tempArray,pDice);
                  clickableDice(pDice);
             }
        }).execute(socket);

    }
});
rollDiceButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        rollDiceButton.setEnabled(false);
        rollDice();
        task = new DiceTask() {
            @Override
            public void onPostExecute(int[] result) {
                tempArray = result;
                printDice(tempArray,pDice);
                clickableDice(pDice);
            }
        }.execute(socket);
    }
});