You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Volley+JSON操作WAMP MySQL:列表行ID传参及报错解决

Hey Saranya, let's break down your problems one by one and get this sorted out—you’ve spent enough time stuck on these!


1. Fixing "No adapter attached; skipping layout"

This error happens because your RecyclerView tries to render before an adapter is attached. Right now, you only set the adapter after Volley finishes fetching data, which can take time. Here’s how to fix it:

Update your initialization flow:

  1. Initialize your RecyclerView, layout manager, empty adapter, and product list early (e.g., in onCreate):

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_activity_layout);
        
        recyclerView = findViewById(R.id.your_recycler_view_id);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        
        // Initialize empty list and adapter first
        productList = new ArrayList<>();
        myadapter = new ProductAdapter(this, productList);
        recyclerView.setAdapter(myadapter);
        
        // Now trigger your Volley request
        fetchProducts();
    }
    
  2. In your Volley onResponse method, replace the setuprecyclerview call with a notify to update the existing adapter:

    try {
        JSONArray array = new JSONArray(response);
        for (int i = 0; i < array.length(); i++) {
            JSONObject product = array.getJSONObject(i);
            Product product1=new Product();
            product1.setName(product.getString("name"));
            product1.setDescription(product.getString("description"));
            productList.add(product1);
        }
        // Notify adapter that data has changed
        myadapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }
    

2. Fixing "org.json.JSONException: Value Connected of type java.lang.String cannot be converted to JSONArray"

This means your PHP script is returning the string "Connected" instead of a valid JSON array. Let’s fix the PHP code:

Step 1: Correct your SQL query

Your original query has syntax errors (typos in table names and incorrect JOIN syntax). Use this instead:

$stmt = $conn->prepare("SELECT domainname.id, domainname.name, domaindescription.description 
                        FROM domainname 
                        INNER JOIN domaindescription ON domainname.id = domaindescription.id_fk");

(Note: I added domainname.id here—we’ll need it later for passing to the next Activity)

Step 2: Ensure PHP outputs only valid JSON

Remove any extra echo "Connected"; statements, and properly format your result as JSON:

<?php
$servername = "localhost";
$username = "your_db_username";
$password = "your_db_password";
$dbname = "your_db_name";

$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die(json_encode(["error" => "Connection failed: " . $conn->connect_error]));
}

$stmt = $conn->prepare("SELECT domainname.id, domainname.name, domaindescription.description 
                        FROM domainname 
                        INNER JOIN domaindescription ON domainname.id = domaindescription.id_fk");
$stmt->execute();
$result = $stmt->get_result();

$products = [];
while($row = $result->fetch_assoc()) {
    $products[] = $row;
}

echo json_encode($products);

$stmt->close();
$conn->close();
?>

3. Passing MySQL Row ID to Another Activity & Displaying Details

Here’s a step-by-step implementation:

Step 1: Update your Product class to include the ID

Add an id field with getters/setters:

public class Product {
    private int id;
    private String name;
    private String description;

    // Constructor
    public Product() {}

    // Getters & Setters
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
}

Step 2: Parse the ID in your Volley response

Update the onResponse block to extract and set the ID:

JSONObject product = array.getJSONObject(i);
Product product1=new Product();
product1.setId(product.getInt("id")); // Add this line
product1.setName(product.getString("name"));
product1.setDescription(product.getString("description"));
productList.add(product1);

Step 3: Add click listener to your RecyclerView Adapter

Modify your ProductAdapter to handle item clicks and pass the ID to the next Activity:

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
    private Context context;
    private List<Product> productList;

    public ProductAdapter(Context context, List<Product> productList) {
        this.context = context;
        this.productList = productList;
    }

    @NonNull
    @Override
    public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.your_item_layout, parent, false);
        return new ProductViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) {
        Product product = productList.get(position);
        holder.tvName.setText(product.getName());
        holder.tvDesc.setText(product.getDescription());

        // Handle item click
        holder.itemView.setOnClickListener(v -> {
            Intent intent = new Intent(context, ProductDetailActivity.class);
            intent.putExtra("PRODUCT_ID", product.getId());
            context.startActivity(intent);
        });
    }

    @Override
    public int getItemCount() {
        return productList.size();
    }

    public static class ProductViewHolder extends RecyclerView.ViewHolder {
        TextView tvName, tvDesc;

        public ProductViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tv_item_name);
            tvDesc = itemView.findViewById(R.id.tv_item_description);
        }
    }
}

Step 4: Create ProductDetailActivity to fetch and display details

This Activity will receive the ID and fetch the corresponding data from your server:

public class ProductDetailActivity extends AppCompatActivity {
    private TextView tvDetailName, tvDetailDesc;
    private static final String URL_DETAIL = "http://your_wamp_ip/get_product_detail.php";

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

        tvDetailName = findViewById(R.id.tv_detail_name);
        tvDetailDesc = findViewById(R.id.tv_detail_description);

        // Get the passed product ID
        int productId = getIntent().getIntExtra("PRODUCT_ID", -1);
        if (productId != -1) {
            fetchProductDetails(productId);
        }
    }

    private void fetchProductDetails(int productId) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                URL_DETAIL + "?id=" + productId,
                response -> {
                    try {
                        JSONObject product = new JSONObject(response);
                        tvDetailName.setText(product.getString("name"));
                        tvDetailDesc.setText(product.getString("description"));
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Toast.makeText(this, "Failed to load details", Toast.LENGTH_SHORT).show();
                    }
                },
                error -> Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show());

        Volley.newRequestQueue(this).add(stringRequest);
    }
}

Step 5: Create the PHP script for detail data (get_product_detail.php)

<?php
$servername = "localhost";
$username = "your_db_username";
$password = "your_db_password";
$dbname = "your_db_name";

$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
    die(json_encode(["error" => "Connection failed: " . $conn->connect_error]));
}

$productId = $_GET['id'];
$stmt = $conn->prepare("SELECT domainname.name, domaindescription.description 
                        FROM domainname 
                        INNER JOIN domaindescription ON domainname.id = domaindescription.id_fk 
                        WHERE domainname.id = ?");
$stmt->bind_param("i", $productId);
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    echo json_encode($result->fetch_assoc());
} else {
    echo json_encode(["error" => "Product not found"]);
}

$stmt->close();
$conn->close();
?>

Quick Reminders:

  • Make sure your Android device and WAMP server are on the same local network
  • Add internet permission to your AndroidManifest.xml:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • Double-check your database credentials in the PHP scripts

内容的提问来源于stack exchange,提问作者Saranya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:32:35