简体   繁体   中英

The final local variable cannot be assigned, since it is defined in an enclosing type java

I have created class childList that implements an interface `GetChildList`` like below:

    package com.example.hakslogin;

import java.util.ArrayList;
import java.util.List;
import com.example.hakslogin.GetChildList;
import com.example.hakslogin.HandleJSON;

public class childList implements GetChildList
{
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";
    public void callFetchJSONChild(){
        HandleJSON obj = new HandleJSON(urlString);
        List<String> list = obj.fetchJSONChild(this);
   }
    @Override
    public void onGetChildList(List<String> list) {
        // here your work with list
        //List<String> child = new ArrayList<String>();
        obj = new HandleJSON(urlString);
        list = obj.fetchJSONChild(this);
    }
}

I have a method fetchJSONChild() like below:

List<String> child = new ArrayList<String>();
           public void fetchJSONChild(final GetChildList callBack){
                final String[] str =  new String[3];
               // final List<String> child = new ArrayList<String>();
            Thread thread = new Thread(new Runnable(){
               @Override
               public void run() {
               try {
                  URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                  conn.setReadTimeout(30000 /* milliseconds */);
                  conn.setConnectTimeout(50000 /* milliseconds */);
                  conn.setRequestMethod("GET");
                  conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                  conn.setRequestProperty("Content-Type", "application/json");
                  conn.setDoInput(true);
                  conn.setUseCaches (false);
                  // Starts the query
                  if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13)
                  {
                   conn.setRequestProperty("Connection", "close"); 
                  }
                  conn.connect();

                  System.out.println("Before url.openStream()");
               InputStream stream = conn.getInputStream();//.openStream();
               System.out.println("After url.openStream()");
            String data = convertStreamToString(stream);
            // for example String data = "1,2,3";
            child.addAll(Arrays.asList(data.split(",")));

            readAndParseJSON(data);
            stream.close();
            callBack.onGetChildList(child);
               } catch (Exception e) {
                  e.printStackTrace();
               }
               }

             thread.start();

         }

And in this method thread is running and I want to get splitted string data that I put into the list<string> into my activity and below is my activity that I called ChildActivity :

package com.example.hakslogin;

import java.util.ArrayList;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.example.hakslogin.GetChildList;

public class ChildActivity extends ActionBarActivity {

    private ListView lv_child;
    List<String> child = new ArrayList<String>();
    Button btn_home;
    Button btn_add;
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);


        obj = new HandleJSON(urlString);
        obj.fetchJSONChild(null);
        lv_child = (ListView)findViewById(R.id.lv_child); 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, child);
        lv_child.setAdapter(adapter);
}

public void onGetChildList(List<String> list) {
   //this method will be called after thread in fetchJSONChild ended
   child = list;
   lv_child = (ListView)findViewById(R.id.lv_child); 
   String arr[]=child.toArray(new String[list.size()]);
   String[] Temp= new String[2];
          Temp[0] = arr[2].toString();
          array.add(Temp[0].split(":")[1]);
          String s = Temp[0].toString();
   ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
   lv_child.setAdapter(adapter);

}

}

I am getting exception android.view.viewrootimpl$calledfromwrongthreadexception when I populate listview from list on onGetChildList method in my ChildActivity .

Kindly suggest me, what I should waiting for reply.

Thanks

final List<String> child = new ArrayList<String>();

and replace

child = new ArrayList<String>(Arrays.asList(data1.split(",")));

with

child.addAll(Arrays.asList(data1.split(","))

1) final is mean that you will never change this variable. So you should use global variable or init it whith empty array and then fill it. Anyway, you have strange algorithm...

2) You start Thread. So all code inside it will be asynchronously. And your operation return child; (in your case) always return null.

So, i recommend you to use callback for your thread cause it's assync operation...

Ok, thats how it's should look:

1) Declare interface:

public interface GetChildList{
        public void onGetChildList(List<String> list);
}

2) In you class (where you call fetchJSONChild() ) implement it:

import com.example.hakslogin.GetChildList;

public class ChildActivity extends ActionBarActivity implements GetChildList {

    Button btn_home;
    Button btn_add;
    private HandleJSON obj;
    public String urlString = "http://192.168.x.xx:xxxx/getdb";

    List<String> child = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);


        obj = new HandleJSON(urlString);
        obj.fetchJSONChild(null);
        lv_child = (ListView)findViewById(R.id.lv_child); 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, child);
        lv_child.setAdapter(adapter);
    }
    Handler mHandler = new Handler() {
      public void handleMessage(android.os.Message msg) {
        lv_child = (ListView)findViewById(R.id.lv_child); 
         String arr[]=child.toArray(new String[list.size()]);
         String[] Temp= new String[2];
         Temp[0] = arr[2].toString();
         array.add(Temp[0].split(":")[1]);
         String s = Temp[0].toString();
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,array);
         lv_child.setAdapter(adapter);
      };
   };



    @Override
    public void onGetChildList(List<String> list) {
       //this method will be called after thread in fetchJSONChild ended
       child = list;
       mHandler.sendEmptyMessage(0);

    }
}

3) Your fetchJSONChild will something like this:

public void fetchJSONChild(final GetChildList callBack){

        final List<String> child = new ArrayList<String>();
        Thread thread = new Thread(new Runnable(){

            @Override
            public void run() {

                try {

                    URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(30000 /* milliseconds */);
                    conn.setConnectTimeout(50000 /* milliseconds */);
                    conn.setRequestMethod("GET");
                    //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
                    conn.setRequestProperty("Content-Type", "application/json");
                    conn.setDoInput(true);
                    //conn.setUseCaches (false);
                    // Starts the query
                    if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) {

                        conn.setRequestProperty("Connection", "close"); 
                    }
                    conn.connect();

                    System.out.println("Before url.openStream()");
                    InputStream stream = conn.getInputStream();//.openStream();
                    System.out.println("After url.openStream()");
                    String data = convertStreamToString(stream);
                    // for examole data = "1,2,3";

                    child.addAll(Arrays.asList(data.split(","));
                    readAndParseJSON(data);
                    stream.close();

                    callBack.onGetChildList(child);
                } catch (Exception e) {

                    e.printStackTrace();
                }
            }
        });
        thread.start(); 
    }

4) in your class where you implemented GetChildList call fetchJSONChild(this)

5) After thread end working it will call onGetChildList where you can process you data.

This type of process which take time and work in background thread to not freeze the screen can't return the processing value. because, method will finish executing before the thread even start!! you start the thread. and when the result is ready in runOnUiThread you do whatever you want. like stop the loading icon and show data to user. that the concept.

List<String> child;
public void fetchJSONChild(){
         //= new ArrayList<String>();
    Thread thread = new Thread(new Runnable(){
       @Override
       public void run() {
       try {
          URL url = new URL("http://192.168.x.xx:xxxx/childform_list/0.0.0.0/8069/new_db/admin/123456");
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
          conn.setReadTimeout(30000 /* milliseconds */);
          conn.setConnectTimeout(50000 /* milliseconds */);
          conn.setRequestMethod("GET");
          //conn.setRequestProperty("User-Agent", "GYUserAgentAndroid");
          conn.setRequestProperty("Content-Type", "application/json");
          conn.setDoInput(true);
          //conn.setUseCaches (false);
          // Starts the query
          if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13)
          {
           conn.setRequestProperty("Connection", "close"); 
          }
          conn.connect();

          System.out.println("Before url.openStream()");
       InputStream stream = conn.getInputStream();//.openStream();
       System.out.println("After url.openStream()");
    String data = convertStreamToString(stream);
    // for examole data = "1,2,3";

    child = new ArrayList<String>(Arrays.asList(data.split(","))); // <<<<---- data not data1!?
    readAndParseJSON(data);

    runOnUiThread(new Runnable() {
                public void run() {
                    // here you can update the ui with the child values.
                    for (int i=0;i<child.size();i++)
                         Log.e("Child", child.get(i));
                }
            });
       stream.close();

       } catch (Exception e) {
          e.printStackTrace();
       }
       }
    });

     thread.start();
 }

Note: this solution works perfectly if the method in the activity class. if not, please say so I can provide a proper solution.

删除child的final声明并使其成为全局变量。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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