0

I trying to create AsyncTask array for my Android project to assign data to TextView's. I need separate tasks for each city data.

My single AsyncTask working ok so I presume main method is fine. Problem starts when I try to create arrays of tasks.

I getting error Attempt to invoke virtual method on null reference

Array task execute exactly same code as single task so problem must be how I created array

I posting whole Main Activity to show what I try to do. With both single and array tasks. I would be grateful for any help.

private LinearLayout editLayout;
private LinearLayout layout1;
private LinearLayout layout2;
private LinearLayout layout3;
private LinearLayout layout4;
int n;
TextView[] city = new TextView[10];
TextView[] time = new TextView[10];
TextView[] temperature = new TextView[10];


private ImageView delete1;
private ImageView delete2;
private ImageView delete3;
private ImageView delete4;

private ImageView condition1;
private ImageView condition2;
private ImageView condition3;
private ImageView condition4;

Weather weather = new Weather();
Task task = new Task();
Task task1 = new Task();
private Task[] myTasks = new Task[10];


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



    editLayout = (LinearLayout) findViewById(R.id.layEdit);
    layout1 = (LinearLayout) findViewById(R.id.lay1);
    layout2 = (LinearLayout) findViewById(R.id.lay2);
    layout3 = (LinearLayout) findViewById(R.id.lay3);
    layout4 = (LinearLayout) findViewById(R.id.lay4);

    city[0] = (TextView) findViewById(R.id.city1);
    city[1] = (TextView) findViewById(R.id.city2);
    city[2] = (TextView) findViewById(R.id.city3);
    city[3] = (TextView) findViewById(R.id.city4);

    time[0] = (TextView) findViewById(R.id.time1);
    time[1] = (TextView) findViewById(R.id.time2);
    time[2] = (TextView) findViewById(R.id.time3);
    time[3] = (TextView) findViewById(R.id.time4);

    temperature[0] = (TextView) findViewById(R.id.temp1);
    temperature[1] = (TextView) findViewById(R.id.temp2);
    temperature[2] = (TextView) findViewById(R.id.temp3);
    temperature[3] = (TextView) findViewById(R.id.temp4);

    delete1 = (ImageView) findViewById(R.id.delete1);
    delete2 = (ImageView) findViewById(R.id.delete2);
    delete3 = (ImageView) findViewById(R.id.delete3);
    delete4 = (ImageView) findViewById(R.id.delete4);

    condition1 = (ImageView) findViewById(R.id.sun1);
    condition2 = (ImageView) findViewById(R.id.sun2);
    condition3 = (ImageView) findViewById(R.id.sun3);
    condition4 = (ImageView) findViewById(R.id.sun4);
    //weatherData("Paris, France");

    //weatherData("Paris, France", 0);
    loadTask(1,"Dublin, Ireland" );




private void loadTask(int sInt, String city){
    this.n=n;
    myTasks[sInt].execute(new String[]{city + "&APPID="+ WeatherApiNumber + "&units=metric"});
}
public void weatherData(String city, int n){
    this.n=n;
    task1.execute(new String[]{city + "&APPID="+ WeatherApiNumber + "&units=metric"});

}
private class Task extends AsyncTask<String, Void, Weather>{

    @Override
    protected Weather doInBackground(String... params) {
        String data = ((new WeatherClient()).getWeatherData(params[0]));
        weather = Parser.getWeather(data);

        return weather;
    }
    @Override
    protected void onPostExecute(Weather weather) {
        super.onPostExecute(weather);

        cityData(n);

    }

}
public void cityData(int n){

    city[n].setText(weather.place.getCity());
    time[n].setText(Integer.toString(weather.place.getTimeZone()));
    temperature[n].setText(Double.toString(weather.temp.getTemp()).substring(0,2));
    //task.cancel(true);


}
public void cityData2(int n){
    ;
    city[n].setText(weather.place.getCity());
    time[n].setText(Integer.toString(weather.place.getTimeZone()));
    temperature[1].setText(Double.toString(weather.temp.getTemp()).substring(0,2));
    //task.cancel(true);

    }
}
Tamir Abutbul
  • 6,472
  • 7
  • 16
  • 44
Tom
  • 27
  • 1
  • 7
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Tamir Abutbul Jun 28 '19 at 17:36

1 Answers1

1

You are not assigning anything to your task array myTasks

in this line you are only initializing the array but not the array items.

private Task[] myTasks = new Task[10];

You should, at some point, assign a task to a cell in myTasks and only then call execute on it

pantos27
  • 601
  • 3
  • 13
  • 1
    Something like myTasks[0] = new Task(); myTasks[1] = new Task(); myTasks[2] = new Task(); myTasks[3] = new Task();? – Tom Jun 28 '19 at 18:39
  • 1
    Exactly. But why would you need a reference to these AsyncTast objects after you launch them? – pantos27 Jun 28 '19 at 19:51
  • I'm very inexperienced with with this. What I plan to do is to create separate layouts all as arrays. Inside them values for city names, temp etc. also as arrays. I want each layout to be generated by separate task. So they work independently in same time. I was planing to use threads first with I'm more familiar. But I saw that everyone using those AsyncTasks now. But now I'm little lost. – Tom Jun 28 '19 at 22:20
  • 1
    you should use some native view that support lists or array (AdapterView) like RecyclerView. – pantos27 Jun 30 '19 at 08:05
  • 1
    Another thing about AsyncTasks, when you launch more than one at the same time, they will not run in parallel unless you explicitly define so using an Executor. By default they run one after another – pantos27 Jun 30 '19 at 08:06
  • Yeah I saw that. I don't understand why this is happening. Those are separate tasks. With separate variables. Why they don't go same time? – Tom Jun 30 '19 at 09:58
  • 1
    That's the default behaviour. If you want to override it use executeonexecutor https://developer.android.com/reference/kotlin/android/os/AsyncTask?hl=en#executeonexecutor – pantos27 Jun 30 '19 at 12:14
  • I did something like that myTasks[n].executeOnExecutor(Task.THREAD_POOL_EXECUTOR, city + "&APPID=" + WeatherApiNumber + "&units=metric"); But it still don't run 2 tasks. One go after another:( – Tom Jun 30 '19 at 13:42
  • I also make this in onPostExecute int a = 0; if(a==0||n==a){ a=n; } if (a!=n) { a = a; } So task use local variable instead calling global that is changed when new task is activated – Tom Jun 30 '19 at 13:47