简体   繁体   English

最终局部变量无法分配,因为它是在封闭类型java中定义的

[英]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: 我已经创建了一个实现了`GetChildList``接口的childList类,如下所示:

    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: 我有一个如下的方法fetchJSONChild()

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 : 在此方法中,线程正在运行,我想将分割后的字符串数据放入到活动中的list<string> ,以下是我称为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 . 当我从ChildActivity onGetChildList方法上的list填充listview时,出现异常android.view.viewrootimpl$calledfromwrongthreadexception

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. 1) final表示您永远不会更改此变量。 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. 2)您启动线程。 So all code inside it will be asynchronously. 因此,其中的所有代码都是异步的。 And your operation return child; 并且您的手术还return child; (in your case) always return null. (在您的情况下)始终返回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: 1)声明界面:

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

2) In you class (where you call fetchJSONChild() ) implement it: 2)在您的类(调用fetchJSONChild() )中实现它:

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: 3)您的fetchJSONChild将如下所示:

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) 4)在实现GetChildList类中调用fetchJSONChild(this)

5) After thread end working it will call onGetChildList where you can process you data. 5)线程结束工作后,它将调用onGetChildList ,您可以在其中处理数据。

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. 当结果在runOnUiThread中准备好时,您可以执行任何操作。 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声明并使其成为全局变量。

暂无
暂无

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

相关问题 Java:最终的局部变量无法分配,因为它是用封闭类型定义的 - Java: the final local variable cannot be assigned, since it was defined in an enclosing type 最终局部变量checkstate不能分配,因为它是用封闭类型定义的 - The final local variable checkstate cannot be assigned, since it is defined in an enclosing type 最终局部变量无法分配,因为它是用封闭类型定义的? - The final local variable cannot be assigned, since it is defined in an enclosing type? 无法分配最终的局部变量,因为它是在封闭类型中定义的 - The final local variable cannot be assigned, since it is defined in an enclosing type 无法分配最终的局部变量标记,因为它是在封闭类型中定义的 - The final local variable token cannot be assigned, since it is defined in an enclosing type 最终的局部变量 dc 无法赋值,因为它是在封闭类型中定义的 - The final local variable dc cannot be assigned, since it is defined in an enclosing type 问题-无法分配最终的局部变量od,因为它是用封闭类型定义的 - Issue - The final local variable od cannot be assigned, since it is defined in an enclosing type 最终局部变量无法分配,因为它是在封闭类型中定义的 - The final local variable cannot be assigned, since it is defined in an enclosed type 绕过“以封闭类型定义的最终局部变量” - Bypassing “final local variable defined in an enclosing type” 最终变量不能以封闭类型分配 - Final variables cannot be assigned in an enclosing type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM